1#include "duckdb/function/function_set.hpp"
2#include "duckdb/function/function_binder.hpp"
3
4namespace duckdb {
5
6ScalarFunctionSet::ScalarFunctionSet() : FunctionSet("") {
7}
8
9ScalarFunctionSet::ScalarFunctionSet(string name) : FunctionSet(std::move(name)) {
10}
11
12ScalarFunctionSet::ScalarFunctionSet(ScalarFunction fun) : FunctionSet(std::move(fun.name)) {
13 functions.push_back(x: std::move(fun));
14}
15
16ScalarFunction 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
27AggregateFunctionSet::AggregateFunctionSet() : FunctionSet("") {
28}
29
30AggregateFunctionSet::AggregateFunctionSet(string name) : FunctionSet(std::move(name)) {
31}
32
33AggregateFunctionSet::AggregateFunctionSet(AggregateFunction fun) : FunctionSet(std::move(fun.name)) {
34 functions.push_back(x: std::move(fun));
35}
36
37AggregateFunction 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
67TableFunctionSet::TableFunctionSet(string name) : FunctionSet(std::move(name)) {
68}
69
70TableFunctionSet::TableFunctionSet(TableFunction fun) : FunctionSet(std::move(fun.name)) {
71 functions.push_back(x: std::move(fun));
72}
73
74TableFunction 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
85PragmaFunctionSet::PragmaFunctionSet(string name) : FunctionSet(std::move(name)) {
86}
87
88PragmaFunctionSet::PragmaFunctionSet(PragmaFunction fun) : FunctionSet(std::move(fun.name)) {
89 functions.push_back(x: std::move(fun));
90}
91
92} // namespace duckdb
93