See More

#include "duckdb/function/function.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/common/types/hash.hpp" #include "duckdb/function/built_in_functions.hpp" #include "duckdb/function/scalar/string_functions.hpp" #include "duckdb/function/scalar_function.hpp" #include "duckdb/parser/parsed_data/pragma_info.hpp" #include "duckdb/planner/expression/bound_aggregate_expression.hpp" #include "duckdb/planner/expression/bound_function_expression.hpp" #include "duckdb/main/extension_entries.hpp" namespace duckdb { FunctionData::~FunctionData() { } bool FunctionData::Equals(const FunctionData *left, const FunctionData *right) { if (left == right) { return true; } if (!left || !right) { return false; } return left->Equals(*right); } TableFunctionData::~TableFunctionData() { } unique_ptr TableFunctionData::Copy() const { throw InternalException("Copy not supported for TableFunctionData"); } bool TableFunctionData::Equals(const FunctionData &other) const { return false; } bool FunctionData::SupportStatementCache() const { return true; } Function::Function(string name_p) : name(std::move(name_p)) { } Function::~Function() { } SimpleFunction::SimpleFunction(string name_p, vector arguments_p, LogicalType varargs_p) : Function(std::move(name_p)), arguments(std::move(arguments_p)), varargs(std::move(varargs_p)) { } SimpleFunction::~SimpleFunction() { } string SimpleFunction::ToString() const { return Function::CallToString(catalog_name, schema_name, name, arguments, varargs); } bool SimpleFunction::HasVarArgs() const { return varargs.id() != LogicalTypeId::INVALID; } SimpleNamedParameterFunction::SimpleNamedParameterFunction(string name_p, vector arguments_p, LogicalType varargs_p) : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)) { } SimpleNamedParameterFunction::~SimpleNamedParameterFunction() { } string SimpleNamedParameterFunction::ToString() const { return Function::CallToString(catalog_name, schema_name, name, arguments, named_parameters); } bool SimpleNamedParameterFunction::HasNamedParameters() const { return !named_parameters.empty(); } BaseScalarFunction::BaseScalarFunction(string name_p, vector arguments_p, LogicalType return_type_p, FunctionStability stability, LogicalType varargs_p, FunctionNullHandling null_handling, FunctionErrors errors) : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)), return_type(std::move(return_type_p)), stability(stability), null_handling(null_handling), errors(errors), collation_handling(FunctionCollationHandling::PROPAGATE_COLLATIONS) { } BaseScalarFunction::~BaseScalarFunction() { } string BaseScalarFunction::ToString() const { return Function::CallToString(catalog_name, schema_name, name, arguments, varargs, return_type); } // add your initializer for new functions here void BuiltinFunctions::Initialize() { RegisterTableScanFunctions(); RegisterSQLiteFunctions(); RegisterReadFunctions(); RegisterTableFunctions(); RegisterArrowFunctions(); RegisterPragmaFunctions(); // initialize collations AddCollation("nocase", LowerFun::GetFunction(), true); AddCollation("noaccent", StripAccentsFun::GetFunction(), true); AddCollation("nfc", NFCNormalizeFun::GetFunction()); RegisterExtensionOverloads(); } hash_t BaseScalarFunction::Hash() const { hash_t hash = return_type.Hash(); for (auto &arg : arguments) { hash = duckdb::CombineHash(hash, arg.Hash()); } return hash; } static bool RequiresCatalogAndSchemaNamePrefix(const string &catalog_name, const string &schema_name) { return !catalog_name.empty() && catalog_name != SYSTEM_CATALOG && !schema_name.empty() && schema_name != DEFAULT_SCHEMA; } string Function::CallToString(const string &catalog_name, const string &schema_name, const string &name, const vector &arguments, const LogicalType &varargs) { string result; if (RequiresCatalogAndSchemaNamePrefix(catalog_name, schema_name)) { result += catalog_name + "." + schema_name + "."; } result += name + "("; vector string_arguments; for (auto &arg : arguments) { string_arguments.push_back(arg.ToString()); } if (varargs.IsValid()) { string_arguments.push_back("[" + varargs.ToString() + "...]"); } result += StringUtil::Join(string_arguments, ", "); return result + ")"; } string Function::CallToString(const string &catalog_name, const string &schema_name, const string &name, const vector &arguments, const LogicalType &varargs, const LogicalType &return_type) { string result = CallToString(catalog_name, schema_name, name, arguments, varargs); result += " -> " + return_type.ToString(); return result; } string Function::CallToString(const string &catalog_name, const string &schema_name, const string &name, const vector &arguments, const named_parameter_type_map_t &named_parameters) { vector input_arguments; input_arguments.reserve(arguments.size() + named_parameters.size()); for (auto &arg : arguments) { input_arguments.push_back(arg.ToString()); } for (auto &kv : named_parameters) { input_arguments.push_back(StringUtil::Format("%s : %s", kv.first, kv.second.ToString())); } string prefix = ""; if (RequiresCatalogAndSchemaNamePrefix(catalog_name, schema_name)) { prefix = StringUtil::Format("%s.%s.", catalog_name, schema_name); } return StringUtil::Format("%s%s(%s)", prefix, name, StringUtil::Join(input_arguments, ", ")); } void Function::EraseArgument(SimpleFunction &bound_function, vector> &arguments, idx_t argument_index) { if (bound_function.original_arguments.empty()) { bound_function.original_arguments = bound_function.arguments; } D_ASSERT(arguments.size() == bound_function.arguments.size()); D_ASSERT(argument_index < arguments.size()); arguments.erase_at(argument_index); bound_function.arguments.erase_at(argument_index); } } // namespace duckdb