230 lines
10 KiB
C++
230 lines
10 KiB
C++
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
// This file is copied from
|
|
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/registerFunctions.h
|
|
// and modified by Doris
|
|
|
|
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <string>
|
|
|
|
#include "exprs/table_function/table_function.h"
|
|
#include "vec/functions/function.h"
|
|
|
|
namespace doris::vectorized {
|
|
|
|
class SimpleFunctionFactory;
|
|
|
|
void register_function_comparison(SimpleFunctionFactory& factory);
|
|
void register_function_comparison_eq_for_null(SimpleFunctionFactory& factory);
|
|
void register_function_hll_cardinality(SimpleFunctionFactory& factory);
|
|
void register_function_hll_empty(SimpleFunctionFactory& factory);
|
|
void register_function_hll_hash(SimpleFunctionFactory& factory);
|
|
void register_function_logical(SimpleFunctionFactory& factory);
|
|
void register_function_case(SimpleFunctionFactory& factory);
|
|
void register_function_cast(SimpleFunctionFactory& factory);
|
|
void register_function_conv(SimpleFunctionFactory& factory);
|
|
void register_function_plus(SimpleFunctionFactory& factory);
|
|
void register_function_minus(SimpleFunctionFactory& factory);
|
|
void register_function_multiply(SimpleFunctionFactory& factory);
|
|
void register_function_divide(SimpleFunctionFactory& factory);
|
|
void register_function_int_div(SimpleFunctionFactory& factory);
|
|
void register_function_bit(SimpleFunctionFactory& factory);
|
|
void register_function_math(SimpleFunctionFactory& factory);
|
|
void register_function_modulo(SimpleFunctionFactory& factory);
|
|
void register_function_bitmap(SimpleFunctionFactory& factory);
|
|
void register_function_bitmap_variadic(SimpleFunctionFactory& factory);
|
|
void register_function_is_null(SimpleFunctionFactory& factory);
|
|
void register_function_is_not_null(SimpleFunctionFactory& factory);
|
|
void register_function_to_time_function(SimpleFunctionFactory& factory);
|
|
void register_function_time_of_function(SimpleFunctionFactory& factory);
|
|
void register_function_string(SimpleFunctionFactory& factory);
|
|
void register_function_date_time_to_string(SimpleFunctionFactory& factory);
|
|
void register_function_date_time_string_to_string(SimpleFunctionFactory& factory);
|
|
void register_function_in(SimpleFunctionFactory& factory);
|
|
void register_function_if(SimpleFunctionFactory& factory);
|
|
void register_function_nullif(SimpleFunctionFactory& factory);
|
|
void register_function_date_time_computation(SimpleFunctionFactory& factory);
|
|
void register_function_timestamp(SimpleFunctionFactory& factory);
|
|
void register_function_utility(SimpleFunctionFactory& factory);
|
|
void register_function_json(SimpleFunctionFactory& factory);
|
|
void register_function_jsonb(SimpleFunctionFactory& factory);
|
|
void register_function_hash(SimpleFunctionFactory& factory);
|
|
void register_function_ifnull(SimpleFunctionFactory& factory);
|
|
void register_function_like(SimpleFunctionFactory& factory);
|
|
void register_function_regexp(SimpleFunctionFactory& factory);
|
|
void register_function_random(SimpleFunctionFactory& factory);
|
|
void register_function_coalesce(SimpleFunctionFactory& factory);
|
|
void register_function_grouping(SimpleFunctionFactory& factory);
|
|
void register_function_datetime_floor_ceil(SimpleFunctionFactory& factory);
|
|
void register_function_convert_tz(SimpleFunctionFactory& factory);
|
|
void register_function_least_greast(SimpleFunctionFactory& factory);
|
|
void register_function_fake(SimpleFunctionFactory& factory);
|
|
void register_function_array(SimpleFunctionFactory& factory);
|
|
void register_function_geo(SimpleFunctionFactory& factory);
|
|
void register_function_multi_string_position(SimpleFunctionFactory& factory);
|
|
void register_function_multi_string_search(SimpleFunctionFactory& factory);
|
|
|
|
void register_function_encryption(SimpleFunctionFactory& factory);
|
|
void register_function_regexp_extract(SimpleFunctionFactory& factory);
|
|
void register_function_hex_variadic(SimpleFunctionFactory& factory);
|
|
|
|
void register_function_url(SimpleFunctionFactory& factory);
|
|
|
|
class SimpleFunctionFactory {
|
|
using Creator = std::function<FunctionBuilderPtr()>;
|
|
using FunctionCreators = phmap::flat_hash_map<std::string, Creator>;
|
|
using FunctionIsVariadic = phmap::flat_hash_set<std::string>;
|
|
|
|
public:
|
|
void register_function(const std::string& name, const Creator& ptr) {
|
|
DataTypes types = ptr()->get_variadic_argument_types();
|
|
// types.empty() means function is not variadic
|
|
if (!types.empty()) {
|
|
function_variadic_set.insert(name);
|
|
}
|
|
|
|
std::string key_str = name;
|
|
if (!types.empty()) {
|
|
for (const auto& type : types) {
|
|
key_str.append(type->get_family_name());
|
|
}
|
|
}
|
|
function_creators[key_str] = ptr;
|
|
}
|
|
|
|
template <class Function>
|
|
void register_function() {
|
|
if constexpr (std::is_base_of<IFunction, Function>::value) {
|
|
register_function(Function::name, &createDefaultFunction<Function>);
|
|
} else {
|
|
register_function(Function::name, &Function::create);
|
|
}
|
|
}
|
|
|
|
template <class Function>
|
|
void register_function(std::string name) {
|
|
function_creators[name] = &createDefaultFunction<Function>;
|
|
}
|
|
|
|
void register_alias(const std::string& name, const std::string& alias) {
|
|
function_alias[alias] = name;
|
|
}
|
|
|
|
FunctionBasePtr get_function(const std::string& name, const ColumnsWithTypeAndName& arguments,
|
|
const DataTypePtr& return_type) {
|
|
std::string key_str = name;
|
|
|
|
if (function_alias.count(name)) {
|
|
key_str = function_alias[name];
|
|
}
|
|
|
|
// if function is variadic, added types_str as key
|
|
if (function_variadic_set.count(key_str)) {
|
|
for (auto& arg : arguments) {
|
|
key_str.append(arg.type->is_nullable()
|
|
? reinterpret_cast<const DataTypeNullable*>(arg.type.get())
|
|
->get_nested_type()
|
|
->get_family_name()
|
|
: arg.type->get_family_name());
|
|
}
|
|
}
|
|
|
|
auto iter = function_creators.find(key_str);
|
|
if (iter != function_creators.end()) {
|
|
return iter->second()->build(arguments, return_type);
|
|
}
|
|
|
|
LOG(WARNING) << fmt::format("Function signature {} is not found", key_str);
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
FunctionCreators function_creators;
|
|
FunctionIsVariadic function_variadic_set;
|
|
std::unordered_map<std::string, std::string> function_alias;
|
|
|
|
template <typename Function>
|
|
static FunctionBuilderPtr createDefaultFunction() {
|
|
return std::make_shared<DefaultFunctionBuilder>(Function::create());
|
|
}
|
|
|
|
public:
|
|
static SimpleFunctionFactory& instance() {
|
|
static std::once_flag oc;
|
|
static SimpleFunctionFactory instance;
|
|
std::call_once(oc, []() {
|
|
register_function_bitmap(instance);
|
|
register_function_bitmap_variadic(instance);
|
|
register_function_hll_cardinality(instance);
|
|
register_function_hll_empty(instance);
|
|
register_function_hll_hash(instance);
|
|
register_function_comparison(instance);
|
|
register_function_logical(instance);
|
|
register_function_case(instance);
|
|
register_function_cast(instance);
|
|
register_function_conv(instance);
|
|
register_function_plus(instance);
|
|
register_function_minus(instance);
|
|
register_function_math(instance);
|
|
register_function_multiply(instance);
|
|
register_function_divide(instance);
|
|
register_function_int_div(instance);
|
|
register_function_modulo(instance);
|
|
register_function_bit(instance);
|
|
register_function_is_null(instance);
|
|
register_function_is_not_null(instance);
|
|
register_function_to_time_function(instance);
|
|
register_function_time_of_function(instance);
|
|
register_function_string(instance);
|
|
register_function_in(instance);
|
|
register_function_if(instance);
|
|
register_function_nullif(instance);
|
|
register_function_date_time_computation(instance);
|
|
register_function_timestamp(instance);
|
|
register_function_utility(instance);
|
|
register_function_date_time_to_string(instance);
|
|
register_function_date_time_string_to_string(instance);
|
|
register_function_json(instance);
|
|
register_function_jsonb(instance);
|
|
register_function_hash(instance);
|
|
register_function_ifnull(instance);
|
|
register_function_comparison_eq_for_null(instance);
|
|
register_function_like(instance);
|
|
register_function_regexp(instance);
|
|
register_function_random(instance);
|
|
register_function_coalesce(instance);
|
|
register_function_grouping(instance);
|
|
register_function_datetime_floor_ceil(instance);
|
|
register_function_convert_tz(instance);
|
|
register_function_least_greast(instance);
|
|
register_function_fake(instance);
|
|
register_function_encryption(instance);
|
|
register_function_regexp_extract(instance);
|
|
register_function_hex_variadic(instance);
|
|
register_function_array(instance);
|
|
register_function_geo(instance);
|
|
register_function_url(instance);
|
|
register_function_multi_string_position(instance);
|
|
register_function_multi_string_search(instance);
|
|
});
|
|
return instance;
|
|
}
|
|
};
|
|
} // namespace doris::vectorized
|