/* * Modified by ScyllaDB * * Copyright (C) 2015-present ScyllaDB */ /* * SPDX-License-Identifier: (AGPL-3.0-or-later and Apache-2.0) */ #pragma once #include "function.hh" #include "aggregate_fcts.hh" #include "time_uuid_fcts.hh" #include "uuid_fcts.hh" #include "bytes_conversion_fcts.hh" #include "aggregate_fcts.hh" #include "bytes_conversion_fcts.hh" #include "cql3/assignment_testable.hh" #include "cql3/cql3_type.hh" #include "cql3/column_identifier.hh" #include "to_string.hh" #include "log.hh" #include namespace cql3 { namespace functions { using declared_t = std::unordered_multimap>; void add_agg_functions(declared_t& funcs); class functions { using declared_t = cql3::functions::declared_t; static thread_local declared_t _declared; private: static std::unordered_multimap> init() noexcept; public: static lw_shared_ptr make_arg_spec(const sstring& receiver_ks, const sstring& receiver_cf, const function& fun, size_t i); public: static shared_ptr get(data_dictionary::database db, const sstring& keyspace, const function_name& name, const std::vector>& provided_args, const sstring& receiver_ks, const sstring& receiver_cf, const column_specification* receiver = nullptr); template static shared_ptr get(data_dictionary::database db, const sstring& keyspace, const function_name& name, AssignmentTestablePtrRange&& provided_args, const sstring& receiver_ks, const sstring& receiver_cf, const column_specification* receiver = nullptr) { const std::vector> args(std::begin(provided_args), std::end(provided_args)); return get(db, keyspace, name, args, receiver_ks, receiver_cf, receiver); } static boost::iterator_range find(const function_name& name); static declared_t::iterator find_iter(const function_name& name, const std::vector& arg_types); static shared_ptr find(const function_name& name, const std::vector& arg_types); static shared_ptr mock_get(const function_name& name, const std::vector& arg_types); static void clear_functions() noexcept; static void add_function(shared_ptr); static void replace_function(shared_ptr); static void remove_function(const function_name& name, const std::vector& arg_types); static std::optional used_by_user_aggregate(const function_name& name); private: template static void with_udf_iter(const function_name& name, const std::vector& arg_types, F&& f); // This method and matchArguments are somewhat duplicate, but this method allows us to provide more precise errors in the common // case where there is no override for a given function. This is thus probably worth the minor code duplication. static void validate_types(data_dictionary::database db, const sstring& keyspace, shared_ptr fun, const std::vector>& provided_args, const sstring& receiver_ks, const sstring& receiver_cf); static assignment_testable::test_result match_arguments(data_dictionary::database db, const sstring& keyspace, shared_ptr fun, const std::vector>& provided_args, const sstring& receiver_ks, const sstring& receiver_cf); static bool type_equals(const std::vector& t1, const std::vector& t2); #if 0 private static class FunctionsMigrationListener implements IMigrationListener { public void onCreateKeyspace(String ksName) { } public void onCreateColumnFamily(String ksName, String cfName) { } public void onCreateUserType(String ksName, String typeName) { } public void onCreateFunction(String ksName, String functionName) { } public void onCreateAggregate(String ksName, String aggregateName) { } public void onUpdateKeyspace(String ksName) { } public void onUpdateColumnFamily(String ksName, String cfName) { } public void onUpdateUserType(String ksName, String typeName) { for (Function function : all()) if (function instanceof UDFunction) ((UDFunction)function).userTypeUpdated(ksName, typeName); } public void onUpdateFunction(String ksName, String functionName) { } public void onUpdateAggregate(String ksName, String aggregateName) { } public void onDropKeyspace(String ksName) { } public void onDropColumnFamily(String ksName, String cfName) { } public void onDropUserType(String ksName, String typeName) { } public void onDropFunction(String ksName, String functionName) { } public void onDropAggregate(String ksName, String aggregateName) { } } #endif }; } }