1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/function/function.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/named_parameter_map.hpp"
12#include "duckdb/common/types/data_chunk.hpp"
13#include "duckdb/common/unordered_set.hpp"
14#include "duckdb/main/external_dependencies.hpp"
15#include "duckdb/parser/column_definition.hpp"
16
17namespace duckdb {
18class CatalogEntry;
19class Catalog;
20class ClientContext;
21class Expression;
22class ExpressionExecutor;
23class Transaction;
24
25class AggregateFunction;
26class AggregateFunctionSet;
27class CopyFunction;
28class PragmaFunction;
29class PragmaFunctionSet;
30class ScalarFunctionSet;
31class ScalarFunction;
32class TableFunctionSet;
33class TableFunction;
34class SimpleFunction;
35
36struct PragmaInfo;
37
38//! The default null handling is NULL in, NULL out
39enum class FunctionNullHandling : uint8_t { DEFAULT_NULL_HANDLING = 0, SPECIAL_HANDLING = 1 };
40enum class FunctionSideEffects : uint8_t { NO_SIDE_EFFECTS = 0, HAS_SIDE_EFFECTS = 1 };
41
42struct FunctionData {
43 DUCKDB_API virtual ~FunctionData();
44
45 DUCKDB_API virtual unique_ptr<FunctionData> Copy() const = 0;
46 DUCKDB_API virtual bool Equals(const FunctionData &other) const = 0;
47 DUCKDB_API static bool Equals(const FunctionData *left, const FunctionData *right);
48
49 template <class TARGET>
50 TARGET &Cast() {
51 D_ASSERT(dynamic_cast<TARGET *>(this));
52 return reinterpret_cast<TARGET &>(*this);
53 }
54 template <class TARGET>
55 const TARGET &Cast() const {
56 D_ASSERT(dynamic_cast<const TARGET *>(this));
57 return reinterpret_cast<const TARGET &>(*this);
58 }
59 // FIXME: this function should be removed in the future
60 template <class TARGET>
61 TARGET &CastNoConst() const {
62 return const_cast<TARGET &>(reinterpret_cast<const TARGET &>(*this));
63 }
64};
65
66struct TableFunctionData : public FunctionData {
67 // used to pass on projections to table functions that support them. NB, can contain COLUMN_IDENTIFIER_ROW_ID
68 vector<idx_t> column_ids;
69
70 DUCKDB_API virtual ~TableFunctionData();
71
72 DUCKDB_API unique_ptr<FunctionData> Copy() const override;
73 DUCKDB_API bool Equals(const FunctionData &other) const override;
74};
75
76struct PyTableFunctionData : public TableFunctionData {
77 //! External dependencies of this table function
78 unique_ptr<ExternalDependency> external_dependency;
79};
80
81struct FunctionParameters {
82 vector<Value> values;
83 named_parameter_map_t named_parameters;
84};
85
86//! Function is the base class used for any type of function (scalar, aggregate or simple function)
87class Function {
88public:
89 DUCKDB_API explicit Function(string name);
90 DUCKDB_API virtual ~Function();
91
92 //! The name of the function
93 string name;
94 //! Additional Information to specify function from it's name
95 string extra_info;
96
97public:
98 //! Returns the formatted string name(arg1, arg2, ...)
99 DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments);
100 //! Returns the formatted string name(arg1, arg2..) -> return_type
101 DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments,
102 const LogicalType &return_type);
103 //! Returns the formatted string name(arg1, arg2.., np1=a, np2=b, ...)
104 DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments,
105 const named_parameter_type_map_t &named_parameters);
106
107 //! Used in the bind to erase an argument from a function
108 DUCKDB_API static void EraseArgument(SimpleFunction &bound_function, vector<unique_ptr<Expression>> &arguments,
109 idx_t argument_index);
110};
111
112class SimpleFunction : public Function {
113public:
114 DUCKDB_API SimpleFunction(string name, vector<LogicalType> arguments,
115 LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
116 DUCKDB_API ~SimpleFunction() override;
117
118 //! The set of arguments of the function
119 vector<LogicalType> arguments;
120 //! The set of original arguments of the function - only set if Function::EraseArgument is called
121 //! Used for (de)serialization purposes
122 vector<LogicalType> original_arguments;
123 //! The type of varargs to support, or LogicalTypeId::INVALID if the function does not accept variable length
124 //! arguments
125 LogicalType varargs;
126
127public:
128 DUCKDB_API virtual string ToString() const;
129
130 DUCKDB_API bool HasVarArgs() const;
131};
132
133class SimpleNamedParameterFunction : public SimpleFunction {
134public:
135 DUCKDB_API SimpleNamedParameterFunction(string name, vector<LogicalType> arguments,
136 LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
137 DUCKDB_API ~SimpleNamedParameterFunction() override;
138
139 //! The named parameters of the function
140 named_parameter_type_map_t named_parameters;
141
142public:
143 DUCKDB_API string ToString() const override;
144 DUCKDB_API bool HasNamedParameters() const;
145};
146
147class BaseScalarFunction : public SimpleFunction {
148public:
149 DUCKDB_API BaseScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
150 FunctionSideEffects side_effects,
151 LogicalType varargs = LogicalType(LogicalTypeId::INVALID),
152 FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING);
153 DUCKDB_API ~BaseScalarFunction() override;
154
155 //! Return type of the function
156 LogicalType return_type;
157 //! Whether or not the function has side effects (e.g. sequence increments, random() functions, NOW()). Functions
158 //! with side-effects cannot be constant-folded.
159 FunctionSideEffects side_effects;
160 //! How this function handles NULL values
161 FunctionNullHandling null_handling;
162
163public:
164 DUCKDB_API hash_t Hash() const;
165
166 DUCKDB_API string ToString() const override;
167};
168
169} // namespace duckdb
170