1#include "duckdb/function/function.hpp"
2
3#include "duckdb/common/string_util.hpp"
4#include "duckdb/common/types/hash.hpp"
5#include "duckdb/function/scalar/string_functions.hpp"
6#include "duckdb/function/scalar_function.hpp"
7#include "duckdb/parser/parsed_data/pragma_info.hpp"
8#include "duckdb/planner/expression/bound_aggregate_expression.hpp"
9#include "duckdb/planner/expression/bound_function_expression.hpp"
10
11namespace duckdb {
12
13FunctionData::~FunctionData() {
14}
15
16bool FunctionData::Equals(const FunctionData *left, const FunctionData *right) {
17 if (left == right) {
18 return true;
19 }
20 if (!left || !right) {
21 return false;
22 }
23 return left->Equals(other: *right);
24}
25
26TableFunctionData::~TableFunctionData() {
27}
28
29unique_ptr<FunctionData> TableFunctionData::Copy() const {
30 throw InternalException("Copy not supported for TableFunctionData");
31}
32
33bool TableFunctionData::Equals(const FunctionData &other) const {
34 return false;
35}
36
37Function::Function(string name_p) : name(std::move(name_p)) {
38}
39Function::~Function() {
40}
41
42SimpleFunction::SimpleFunction(string name_p, vector<LogicalType> arguments_p, LogicalType varargs_p)
43 : Function(std::move(name_p)), arguments(std::move(arguments_p)), varargs(std::move(varargs_p)) {
44}
45
46SimpleFunction::~SimpleFunction() {
47}
48
49string SimpleFunction::ToString() const {
50 return Function::CallToString(name, arguments);
51}
52
53bool SimpleFunction::HasVarArgs() const {
54 return varargs.id() != LogicalTypeId::INVALID;
55}
56
57SimpleNamedParameterFunction::SimpleNamedParameterFunction(string name_p, vector<LogicalType> arguments_p,
58 LogicalType varargs_p)
59 : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)) {
60}
61
62SimpleNamedParameterFunction::~SimpleNamedParameterFunction() {
63}
64
65string SimpleNamedParameterFunction::ToString() const {
66 return Function::CallToString(name, arguments, named_parameters);
67}
68
69bool SimpleNamedParameterFunction::HasNamedParameters() const {
70 return !named_parameters.empty();
71}
72
73BaseScalarFunction::BaseScalarFunction(string name_p, vector<LogicalType> arguments_p, LogicalType return_type_p,
74 FunctionSideEffects side_effects, LogicalType varargs_p,
75 FunctionNullHandling null_handling)
76 : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)),
77 return_type(std::move(return_type_p)), side_effects(side_effects), null_handling(null_handling) {
78}
79
80BaseScalarFunction::~BaseScalarFunction() {
81}
82
83string BaseScalarFunction::ToString() const {
84 return Function::CallToString(name, arguments, return_type);
85}
86
87// add your initializer for new functions here
88void BuiltinFunctions::Initialize() {
89 RegisterTableScanFunctions();
90 RegisterSQLiteFunctions();
91 RegisterReadFunctions();
92 RegisterTableFunctions();
93 RegisterArrowFunctions();
94
95 RegisterDistributiveAggregates();
96
97 RegisterGenericFunctions();
98 RegisterOperators();
99 RegisterSequenceFunctions();
100 RegisterStringFunctions();
101 RegisterNestedFunctions();
102
103 RegisterPragmaFunctions();
104
105 // initialize collations
106 AddCollation(name: "nocase", function: LowerFun::GetFunction(), combinable: true);
107 AddCollation(name: "noaccent", function: StripAccentsFun::GetFunction());
108 AddCollation(name: "nfc", function: NFCNormalizeFun::GetFunction());
109}
110
111hash_t BaseScalarFunction::Hash() const {
112 hash_t hash = return_type.Hash();
113 for (auto &arg : arguments) {
114 duckdb::CombineHash(left: hash, right: arg.Hash());
115 }
116 return hash;
117}
118
119string Function::CallToString(const string &name, const vector<LogicalType> &arguments) {
120 string result = name + "(";
121 result += StringUtil::Join(input: arguments, count: arguments.size(), separator: ", ",
122 f: [](const LogicalType &argument) { return argument.ToString(); });
123 return result + ")";
124}
125
126string Function::CallToString(const string &name, const vector<LogicalType> &arguments,
127 const LogicalType &return_type) {
128 string result = CallToString(name, arguments);
129 result += " -> " + return_type.ToString();
130 return result;
131}
132
133string Function::CallToString(const string &name, const vector<LogicalType> &arguments,
134 const named_parameter_type_map_t &named_parameters) {
135 vector<string> input_arguments;
136 input_arguments.reserve(n: arguments.size() + named_parameters.size());
137 for (auto &arg : arguments) {
138 input_arguments.push_back(x: arg.ToString());
139 }
140 for (auto &kv : named_parameters) {
141 input_arguments.push_back(x: StringUtil::Format(fmt_str: "%s : %s", params: kv.first, params: kv.second.ToString()));
142 }
143 return StringUtil::Format(fmt_str: "%s(%s)", params: name, params: StringUtil::Join(input: input_arguments, separator: ", "));
144}
145
146void Function::EraseArgument(SimpleFunction &bound_function, vector<unique_ptr<Expression>> &arguments,
147 idx_t argument_index) {
148 if (bound_function.original_arguments.empty()) {
149 bound_function.original_arguments = bound_function.arguments;
150 }
151 D_ASSERT(arguments.size() == bound_function.arguments.size());
152 D_ASSERT(argument_index < arguments.size());
153 arguments.erase(position: arguments.begin() + argument_index);
154 bound_function.arguments.erase(position: bound_function.arguments.begin() + argument_index);
155}
156
157} // namespace duckdb
158