1#include "duckdb/function/scalar_function.hpp"
2
3namespace duckdb {
4
5FunctionLocalState::~FunctionLocalState() {
6}
7
8ScalarFunction::ScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
9 scalar_function_t function, bind_scalar_function_t bind,
10 dependency_function_t dependency, function_statistics_t statistics,
11 init_local_state_t init_local_state, LogicalType varargs,
12 FunctionSideEffects side_effects, FunctionNullHandling null_handling)
13 : BaseScalarFunction(std::move(name), std::move(arguments), std::move(return_type), side_effects,
14 std::move(varargs), null_handling),
15 function(std::move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency),
16 statistics(statistics), serialize(nullptr), deserialize(nullptr) {
17}
18
19ScalarFunction::ScalarFunction(vector<LogicalType> arguments, LogicalType return_type, scalar_function_t function,
20 bind_scalar_function_t bind, dependency_function_t dependency,
21 function_statistics_t statistics, init_local_state_t init_local_state,
22 LogicalType varargs, FunctionSideEffects side_effects,
23 FunctionNullHandling null_handling)
24 : ScalarFunction(string(), std::move(arguments), std::move(return_type), std::move(function), bind, dependency,
25 statistics, init_local_state, std::move(varargs), side_effects, null_handling) {
26}
27
28bool ScalarFunction::operator==(const ScalarFunction &rhs) const {
29 return CompareScalarFunctionT(other: rhs.function) && bind == rhs.bind && dependency == rhs.dependency &&
30 statistics == rhs.statistics;
31}
32bool ScalarFunction::operator!=(const ScalarFunction &rhs) const {
33 return !(*this == rhs);
34}
35
36bool ScalarFunction::Equal(const ScalarFunction &rhs) const {
37 // number of types
38 if (this->arguments.size() != rhs.arguments.size()) {
39 return false;
40 }
41 // argument types
42 for (idx_t i = 0; i < this->arguments.size(); ++i) {
43 if (this->arguments[i] != rhs.arguments[i]) {
44 return false;
45 }
46 }
47 // return type
48 if (this->return_type != rhs.return_type) {
49 return false;
50 }
51 // varargs
52 if (this->varargs != rhs.varargs) {
53 return false;
54 }
55
56 return true; // they are equal
57}
58
59bool ScalarFunction::CompareScalarFunctionT(const scalar_function_t &other) const {
60 typedef void(scalar_function_ptr_t)(DataChunk &, ExpressionState &, Vector &);
61
62 auto func_ptr = (scalar_function_ptr_t **)function.template target<scalar_function_ptr_t *>(); // NOLINT
63 auto other_ptr = (scalar_function_ptr_t **)other.template target<scalar_function_ptr_t *>(); // NOLINT
64
65 // Case the functions were created from lambdas the target will return a nullptr
66 if (!func_ptr && !other_ptr) {
67 return true;
68 }
69 if (func_ptr == nullptr || other_ptr == nullptr) {
70 // scalar_function_t (std::functions) from lambdas cannot be compared
71 return false;
72 }
73 return CastPointerToValue(src: *func_ptr) == CastPointerToValue(src: *other_ptr);
74}
75
76void ScalarFunction::NopFunction(DataChunk &input, ExpressionState &state, Vector &result) {
77 D_ASSERT(input.ColumnCount() >= 1);
78 result.Reference(other&: input.data[0]);
79}
80
81} // namespace duckdb
82