1 | #include "duckdb/function/function_set.hpp" |
2 | #include "duckdb/function/function_binder.hpp" |
3 | |
4 | namespace duckdb { |
5 | |
6 | ScalarFunctionSet::ScalarFunctionSet() : FunctionSet("" ) { |
7 | } |
8 | |
9 | ScalarFunctionSet::ScalarFunctionSet(string name) : FunctionSet(std::move(name)) { |
10 | } |
11 | |
12 | ScalarFunctionSet::ScalarFunctionSet(ScalarFunction fun) : FunctionSet(std::move(fun.name)) { |
13 | functions.push_back(x: std::move(fun)); |
14 | } |
15 | |
16 | ScalarFunction ScalarFunctionSet::GetFunctionByArguments(ClientContext &context, const vector<LogicalType> &arguments) { |
17 | string error; |
18 | FunctionBinder binder(context); |
19 | idx_t index = binder.BindFunction(name, functions&: *this, arguments, error); |
20 | if (index == DConstants::INVALID_INDEX) { |
21 | throw InternalException("Failed to find function %s(%s)\n%s" , name, StringUtil::ToString(input: arguments, separator: "," ), |
22 | error); |
23 | } |
24 | return GetFunctionByOffset(offset: index); |
25 | } |
26 | |
27 | AggregateFunctionSet::AggregateFunctionSet() : FunctionSet("" ) { |
28 | } |
29 | |
30 | AggregateFunctionSet::AggregateFunctionSet(string name) : FunctionSet(std::move(name)) { |
31 | } |
32 | |
33 | AggregateFunctionSet::AggregateFunctionSet(AggregateFunction fun) : FunctionSet(std::move(fun.name)) { |
34 | functions.push_back(x: std::move(fun)); |
35 | } |
36 | |
37 | AggregateFunction AggregateFunctionSet::GetFunctionByArguments(ClientContext &context, |
38 | const vector<LogicalType> &arguments) { |
39 | string error; |
40 | FunctionBinder binder(context); |
41 | idx_t index = binder.BindFunction(name, functions&: *this, arguments, error); |
42 | if (index == DConstants::INVALID_INDEX) { |
43 | // check if the arguments are a prefix of any of the arguments |
44 | // this is used for functions such as quantile or string_agg that delete part of their arguments during bind |
45 | // FIXME: we should come up with a better solution here |
46 | for (auto &func : functions) { |
47 | if (arguments.size() >= func.arguments.size()) { |
48 | continue; |
49 | } |
50 | bool is_prefix = true; |
51 | for (idx_t k = 0; k < arguments.size(); k++) { |
52 | if (arguments[k] != func.arguments[k]) { |
53 | is_prefix = false; |
54 | break; |
55 | } |
56 | } |
57 | if (is_prefix) { |
58 | return func; |
59 | } |
60 | } |
61 | throw InternalException("Failed to find function %s(%s)\n%s" , name, StringUtil::ToString(input: arguments, separator: "," ), |
62 | error); |
63 | } |
64 | return GetFunctionByOffset(offset: index); |
65 | } |
66 | |
67 | TableFunctionSet::TableFunctionSet(string name) : FunctionSet(std::move(name)) { |
68 | } |
69 | |
70 | TableFunctionSet::TableFunctionSet(TableFunction fun) : FunctionSet(std::move(fun.name)) { |
71 | functions.push_back(x: std::move(fun)); |
72 | } |
73 | |
74 | TableFunction TableFunctionSet::GetFunctionByArguments(ClientContext &context, const vector<LogicalType> &arguments) { |
75 | string error; |
76 | FunctionBinder binder(context); |
77 | idx_t index = binder.BindFunction(name, functions&: *this, arguments, error); |
78 | if (index == DConstants::INVALID_INDEX) { |
79 | throw InternalException("Failed to find function %s(%s)\n%s" , name, StringUtil::ToString(input: arguments, separator: "," ), |
80 | error); |
81 | } |
82 | return GetFunctionByOffset(offset: index); |
83 | } |
84 | |
85 | PragmaFunctionSet::PragmaFunctionSet(string name) : FunctionSet(std::move(name)) { |
86 | } |
87 | |
88 | PragmaFunctionSet::PragmaFunctionSet(PragmaFunction fun) : FunctionSet(std::move(fun.name)) { |
89 | functions.push_back(x: std::move(fun)); |
90 | } |
91 | |
92 | } // namespace duckdb |
93 | |