This is an automated email from the ASF dual-hosted git repository. ravindra pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push: new 48200c4 ARROW-5892 : [C++][Gandiva] Support function aliases 48200c4 is described below commit 48200c48d86ff9526787f96ce0b34a0553db44b1 Author: Prudhvi Porandla <prudhvi.poran...@icloud.com> AuthorDate: Fri Jul 12 17:28:13 2019 +0530 ARROW-5892 : [C++][Gandiva] Support function aliases Access precompiled functions with different names. Author: Prudhvi Porandla <prudhvi.poran...@icloud.com> Author: pprudhvi <30983614+pprud...@users.noreply.github.com> Closes #4835 from pprudhvi/func-aliases and squashes the following commits: 39bc74f94 <Prudhvi Porandla> enclose in parens only when required a5ad80efa <Prudhvi Porandla> lint 8eb9cc19a <Prudhvi Porandla> do not pass initializer list through macros directly 430b97fcc <Prudhvi Porandla> refactor: make aliases const-ref, use gmock matcher 727bbd055 <pprudhvi> Merge branch 'master' into func-aliases 0610288cd <Prudhvi Porandla> add base name at front. add get_all_signatures method in glib 0376231ed <Prudhvi Porandla> add java test, rename iterator pointer names e0d02b1a0 <Prudhvi Porandla> use nullptr instead of NULLPTR 35407031f <Prudhvi Porandla> use native funciton's last func signature in glib ee2ef21e0 <Prudhvi Porandla> refactor: descriptive member names in func_registry 61c29a214 <Prudhvi Porandla> add aliases to truncate, divide, mod 090b6a7eb <Prudhvi Porandla> support function aliases --- c_glib/gandiva-glib/native-function.cpp | 29 +++++- cpp/src/gandiva/expression_registry.cc | 37 +++++-- cpp/src/gandiva/expression_registry.h | 13 ++- cpp/src/gandiva/expression_registry_test.cc | 9 +- cpp/src/gandiva/function_registry.cc | 8 +- cpp/src/gandiva/function_registry.h | 1 + cpp/src/gandiva/function_registry_arithmetic.cc | 80 +++++++-------- cpp/src/gandiva/function_registry_common.h | 111 ++++++++++++--------- cpp/src/gandiva/function_registry_datetime.cc | 44 ++++---- cpp/src/gandiva/function_registry_hash.cc | 34 +++---- cpp/src/gandiva/function_registry_math_ops.cc | 73 +++++++------- cpp/src/gandiva/function_registry_string.cc | 58 +++++------ cpp/src/gandiva/function_registry_test.cc | 3 +- .../function_registry_timestamp_arithmetic.cc | 88 ++++++++-------- cpp/src/gandiva/native_function.h | 18 ++-- .../gandiva/evaluator/ExpressionRegistryTest.java | 10 ++ 16 files changed, 356 insertions(+), 260 deletions(-) diff --git a/c_glib/gandiva-glib/native-function.cpp b/c_glib/gandiva-glib/native-function.cpp index d069147..f2f15ac 100644 --- a/c_glib/gandiva-glib/native-function.cpp +++ b/c_glib/gandiva-glib/native-function.cpp @@ -106,11 +106,36 @@ ggandiva_native_function_get_signature(GGandivaNativeFunction *native_function) { auto gandiva_native_function = ggandiva_native_function_get_raw(native_function); - auto &gandiva_function_signature = gandiva_native_function->signature(); + auto &gandiva_function_signature = gandiva_native_function->signatures().front(); return ggandiva_function_signature_new_raw(&gandiva_function_signature); } /** + * ggandiva_native_function_get_all_signatures: + * @native_function: A #GGandivaNativeFunction. + * + * Returns: (transfer full): A List of #GGandivaFunctionSignature supported by + * the native function. + * + * Since: ?? + */ +GList * +ggandiva_native_function_get_all_signatures(GGandivaNativeFunction *native_function) +{ + auto gandiva_native_function = + ggandiva_native_function_get_raw(native_function); + + GList *function_signatures = nullptr; + for (auto& function_sig_raw : gandiva_native_function->signatures()) { + auto function_sig = ggandiva_function_signature_new_raw(&function_sig_raw); + function_signatures = g_list_prepend(function_signatures, function_sig); + } + function_signatures = g_list_reverse(function_signatures); + + return function_signatures; +} + +/** * ggandiva_native_function_equal: * @native_function: A #GGandivaNativeFunction. * @other_native_function: A #GGandivaNativeFunction to be compared. @@ -145,7 +170,7 @@ ggandiva_native_function_to_string(GGandivaNativeFunction *native_function) { auto gandiva_native_function = ggandiva_native_function_get_raw(native_function); - auto gandiva_function_signature = gandiva_native_function->signature(); + auto gandiva_function_signature = gandiva_native_function->signatures().front(); return g_strdup(gandiva_function_signature.ToString().c_str()); } diff --git a/cpp/src/gandiva/expression_registry.cc b/cpp/src/gandiva/expression_registry.cc index d062963..b884bf6 100644 --- a/cpp/src/gandiva/expression_registry.cc +++ b/cpp/src/gandiva/expression_registry.cc @@ -30,28 +30,51 @@ ExpressionRegistry::ExpressionRegistry() { ExpressionRegistry::~ExpressionRegistry() {} +// to be used only to create function_signature_start +ExpressionRegistry::FunctionSignatureIterator::FunctionSignatureIterator( + native_func_iterator_type nf_it, native_func_iterator_type nf_it_end) + : native_func_it_{nf_it}, + native_func_it_end_{nf_it_end}, + func_sig_it_{&(nf_it->signatures().front())} {} + +// to be used only to create function_signature_end +ExpressionRegistry::FunctionSignatureIterator::FunctionSignatureIterator( + func_sig_iterator_type fs_it) + : native_func_it_{nullptr}, native_func_it_end_{nullptr}, func_sig_it_{fs_it} {} + const ExpressionRegistry::FunctionSignatureIterator ExpressionRegistry::function_signature_begin() { - return FunctionSignatureIterator(function_registry_->begin()); + return FunctionSignatureIterator(function_registry_->begin(), + function_registry_->end()); } const ExpressionRegistry::FunctionSignatureIterator ExpressionRegistry::function_signature_end() const { - return FunctionSignatureIterator(function_registry_->end()); + return FunctionSignatureIterator(&(*(function_registry_->back()->signatures().end()))); } bool ExpressionRegistry::FunctionSignatureIterator::operator!=( const FunctionSignatureIterator& func_sign_it) { - return func_sign_it.it_ != this->it_; + return func_sign_it.func_sig_it_ != this->func_sig_it_; } FunctionSignature ExpressionRegistry::FunctionSignatureIterator::operator*() { - return (*it_).signature(); + return *func_sig_it_; } -ExpressionRegistry::iterator ExpressionRegistry::FunctionSignatureIterator::operator++( - int increment) { - return it_++; +ExpressionRegistry::func_sig_iterator_type ExpressionRegistry::FunctionSignatureIterator:: +operator++(int increment) { + ++func_sig_it_; + // point func_sig_it_ to first signature of next nativefunction if func_sig_it_ is + // pointing to end + if (func_sig_it_ == &(*native_func_it_->signatures().end())) { + ++native_func_it_; + if (native_func_it_ == native_func_it_end_) { // last native function + return func_sig_it_; + } + func_sig_it_ = &(native_func_it_->signatures().front()); + } + return func_sig_it_; } DataTypeVector ExpressionRegistry::supported_types_ = diff --git a/cpp/src/gandiva/expression_registry.h b/cpp/src/gandiva/expression_registry.h index 97197f2..bcebbe6 100644 --- a/cpp/src/gandiva/expression_registry.h +++ b/cpp/src/gandiva/expression_registry.h @@ -36,22 +36,27 @@ class FunctionRegistry; /// data types and functions supported by Gandiva. class GANDIVA_EXPORT ExpressionRegistry { public: - using iterator = const NativeFunction*; + using native_func_iterator_type = const NativeFunction*; + using func_sig_iterator_type = const FunctionSignature*; ExpressionRegistry(); ~ExpressionRegistry(); static DataTypeVector supported_types() { return supported_types_; } class GANDIVA_EXPORT FunctionSignatureIterator { public: - explicit FunctionSignatureIterator(iterator it) : it_(it) {} + explicit FunctionSignatureIterator(native_func_iterator_type nf_it, + native_func_iterator_type nf_it_end_); + explicit FunctionSignatureIterator(func_sig_iterator_type fs_it); bool operator!=(const FunctionSignatureIterator& func_sign_it); FunctionSignature operator*(); - iterator operator++(int); + func_sig_iterator_type operator++(int); private: - iterator it_; + native_func_iterator_type native_func_it_; + const native_func_iterator_type native_func_it_end_; + func_sig_iterator_type func_sig_it_; }; const FunctionSignatureIterator function_signature_begin(); const FunctionSignatureIterator function_signature_end() const; diff --git a/cpp/src/gandiva/expression_registry_test.cc b/cpp/src/gandiva/expression_registry_test.cc index c50e136..c254ff4 100644 --- a/cpp/src/gandiva/expression_registry_test.cc +++ b/cpp/src/gandiva/expression_registry_test.cc @@ -43,10 +43,11 @@ TEST_F(TestExpressionRegistry, VerifySupportedFunctions) { functions.push_back((*iter)); } for (auto& iter : registry_) { - auto function = iter.signature(); - auto element = std::find(functions.begin(), functions.end(), function); - EXPECT_NE(element, functions.end()) - << "function " << iter.pc_name() << " missing in supported functions.\n"; + for (auto& func_iter : iter.signatures()) { + auto element = std::find(functions.begin(), functions.end(), func_iter); + EXPECT_NE(element, functions.end()) << "function signature " << func_iter.ToString() + << " missing in supported functions.\n"; + } } } diff --git a/cpp/src/gandiva/function_registry.cc b/cpp/src/gandiva/function_registry.cc index 43eda4d..d5d015c 100644 --- a/cpp/src/gandiva/function_registry.cc +++ b/cpp/src/gandiva/function_registry.cc @@ -37,6 +37,10 @@ FunctionRegistry::iterator FunctionRegistry::end() const { return &(*pc_registry_.end()); } +FunctionRegistry::iterator FunctionRegistry::back() const { + return &(pc_registry_.back()); +} + std::vector<NativeFunction> FunctionRegistry::pc_registry_; SignatureMap FunctionRegistry::pc_registry_map_ = InitPCMap(); @@ -62,7 +66,9 @@ SignatureMap FunctionRegistry::InitPCMap() { pc_registry_.insert(std::end(pc_registry_), v6.begin(), v6.end()); for (auto& elem : pc_registry_) { - map.insert(std::make_pair(&(elem.signature()), &elem)); + for (auto& func_signature : elem.signatures()) { + map.insert(std::make_pair(&(func_signature), &elem)); + } } return map; diff --git a/cpp/src/gandiva/function_registry.h b/cpp/src/gandiva/function_registry.h index f7aa3de..dadc831 100644 --- a/cpp/src/gandiva/function_registry.h +++ b/cpp/src/gandiva/function_registry.h @@ -36,6 +36,7 @@ class GANDIVA_EXPORT FunctionRegistry { iterator begin() const; iterator end() const; + iterator back() const; private: static SignatureMap InitPCMap(); diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc b/cpp/src/gandiva/function_registry_arithmetic.cc index e3fb447..8cbfdaf 100644 --- a/cpp/src/gandiva/function_registry_arithmetic.cc +++ b/cpp/src/gandiva/function_registry_arithmetic.cc @@ -20,23 +20,24 @@ namespace gandiva { -#define BINARY_SYMMETRIC_FN(name) NUMERIC_TYPES(BINARY_SYMMETRIC_SAFE_NULL_IF_NULL, name) +#define BINARY_SYMMETRIC_FN(name, ALIASES) \ + NUMERIC_TYPES(BINARY_SYMMETRIC_SAFE_NULL_IF_NULL, name, ALIASES) -#define BINARY_RELATIONAL_BOOL_FN(name) \ - NUMERIC_BOOL_DATE_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name) +#define BINARY_RELATIONAL_BOOL_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name, ALIASES) -#define BINARY_RELATIONAL_BOOL_DATE_FN(name) \ - NUMERIC_DATE_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name) +#define BINARY_RELATIONAL_BOOL_DATE_FN(name, ALIASES) \ + NUMERIC_DATE_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name, ALIASES) -#define UNARY_CAST_TO_FLOAT64(name) UNARY_SAFE_NULL_IF_NULL(castFLOAT8, name, float64) +#define UNARY_CAST_TO_FLOAT64(name) UNARY_SAFE_NULL_IF_NULL(castFLOAT8, {}, name, float64) -#define UNARY_CAST_TO_FLOAT32(name) UNARY_SAFE_NULL_IF_NULL(castFLOAT4, name, float32) +#define UNARY_CAST_TO_FLOAT32(name) UNARY_SAFE_NULL_IF_NULL(castFLOAT4, {}, name, float32) std::vector<NativeFunction> GetArithmeticFunctionRegistry() { static std::vector<NativeFunction> arithmetic_fn_registry_ = { - UNARY_SAFE_NULL_IF_NULL(not, boolean, boolean), - UNARY_SAFE_NULL_IF_NULL(castBIGINT, int32, int64), - UNARY_SAFE_NULL_IF_NULL(castBIGINT, decimal128, int64), + UNARY_SAFE_NULL_IF_NULL(not, {}, boolean, boolean), + UNARY_SAFE_NULL_IF_NULL(castBIGINT, {}, int32, int64), + UNARY_SAFE_NULL_IF_NULL(castBIGINT, {}, decimal128, int64), // cast to float32 UNARY_CAST_TO_FLOAT32(int32), UNARY_CAST_TO_FLOAT32(int64), @@ -46,40 +47,41 @@ std::vector<NativeFunction> GetArithmeticFunctionRegistry() { UNARY_CAST_TO_FLOAT64(float32), UNARY_CAST_TO_FLOAT64(decimal128), // cast to decimal - UNARY_SAFE_NULL_IF_NULL(castDECIMAL, int32, decimal128), - UNARY_SAFE_NULL_IF_NULL(castDECIMAL, int64, decimal128), - UNARY_SAFE_NULL_IF_NULL(castDECIMAL, float32, decimal128), - UNARY_SAFE_NULL_IF_NULL(castDECIMAL, float64, decimal128), - UNARY_SAFE_NULL_IF_NULL(castDECIMAL, decimal128, decimal128), - UNARY_UNSAFE_NULL_IF_NULL(castDECIMAL, utf8, decimal128), + UNARY_SAFE_NULL_IF_NULL(castDECIMAL, {}, int32, decimal128), + UNARY_SAFE_NULL_IF_NULL(castDECIMAL, {}, int64, decimal128), + UNARY_SAFE_NULL_IF_NULL(castDECIMAL, {}, float32, decimal128), + UNARY_SAFE_NULL_IF_NULL(castDECIMAL, {}, float64, decimal128), + UNARY_SAFE_NULL_IF_NULL(castDECIMAL, {}, decimal128, decimal128), + UNARY_UNSAFE_NULL_IF_NULL(castDECIMAL, {}, utf8, decimal128), - UNARY_SAFE_NULL_IF_NULL(castDATE, int64, date64), + UNARY_SAFE_NULL_IF_NULL(castDATE, {}, int64, date64), // add/sub/multiply/divide/mod - BINARY_SYMMETRIC_FN(add), BINARY_SYMMETRIC_FN(subtract), - BINARY_SYMMETRIC_FN(multiply), - NUMERIC_TYPES(BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL, divide), - BINARY_GENERIC_SAFE_NULL_IF_NULL(mod, int64, int32, int32), - BINARY_GENERIC_SAFE_NULL_IF_NULL(mod, int64, int64, int64), - BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(add, decimal128), - BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(subtract, decimal128), - BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(multiply, decimal128), - BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(divide, decimal128), - BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, decimal128), - BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, float64), + BINARY_SYMMETRIC_FN(add, {}), BINARY_SYMMETRIC_FN(subtract, {}), + BINARY_SYMMETRIC_FN(multiply, {}), + NUMERIC_TYPES(BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL, divide, {"div"}), + BINARY_GENERIC_SAFE_NULL_IF_NULL(mod, {"modulo"}, int64, int32, int32), + BINARY_GENERIC_SAFE_NULL_IF_NULL(mod, {"modulo"}, int64, int64, int64), + BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(add, {}, decimal128), + BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(subtract, {}, decimal128), + BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(multiply, {}, decimal128), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(divide, {"div"}, decimal128), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, {"modulo"}, decimal128), + BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(mod, {"modulo"}, float64), // compare functions - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(equal, decimal128), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(not_equal, decimal128), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(less_than, decimal128), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(less_than_or_equal_to, decimal128), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(greater_than, decimal128), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(greater_than_or_equal_to, decimal128), - BINARY_RELATIONAL_BOOL_FN(equal), BINARY_RELATIONAL_BOOL_FN(not_equal), - BINARY_RELATIONAL_BOOL_DATE_FN(less_than), - BINARY_RELATIONAL_BOOL_DATE_FN(less_than_or_equal_to), - BINARY_RELATIONAL_BOOL_DATE_FN(greater_than), - BINARY_RELATIONAL_BOOL_DATE_FN(greater_than_or_equal_to)}; + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(equal, {}, decimal128), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(not_equal, {}, decimal128), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(less_than, {}, decimal128), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(less_than_or_equal_to, {}, decimal128), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(greater_than, {}, decimal128), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(greater_than_or_equal_to, {}, decimal128), + BINARY_RELATIONAL_BOOL_FN(equal, ({"eq", "same"})), + BINARY_RELATIONAL_BOOL_FN(not_equal, {}), + BINARY_RELATIONAL_BOOL_DATE_FN(less_than, {}), + BINARY_RELATIONAL_BOOL_DATE_FN(less_than_or_equal_to, {}), + BINARY_RELATIONAL_BOOL_DATE_FN(greater_than, {}), + BINARY_RELATIONAL_BOOL_DATE_FN(greater_than_or_equal_to, {})}; return arithmetic_fn_registry_; } diff --git a/cpp/src/gandiva/function_registry_common.h b/cpp/src/gandiva/function_registry_common.h index f6a3d14..b6119f8 100644 --- a/cpp/src/gandiva/function_registry_common.h +++ b/cpp/src/gandiva/function_registry_common.h @@ -19,6 +19,7 @@ #define GANDIVA_FUNCTION_REGISTRY_COMMON_H #include <memory> +#include <string> #include <unordered_map> #include <vector> @@ -74,8 +75,9 @@ typedef std::unordered_map<const FunctionSignature*, const NativeFunction*, KeyH // - NULL handling is of type NULL_IF_NULL // // The pre-compiled fn name includes the base name & input type names. eg. add_int32_int32 -#define BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE(), TYPE()}, TYPE(), kResultNullIfNull, \ +#define BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{TYPE(), TYPE()}, TYPE(), kResultNullIfNull, \ ARROW_STRINGIFY(NAME##_##TYPE##_##TYPE)) // Binary functions that : @@ -84,22 +86,24 @@ typedef std::unordered_map<const FunctionSignature*, const NativeFunction*, KeyH // - can return error. // // The pre-compiled fn name includes the base name & input type names. eg. add_int32_int32 -#define BINARY_UNSAFE_NULL_IF_NULL(NAME, IN_TYPE, OUT_TYPE) \ - NativeFunction(#NAME, DataTypeVector{IN_TYPE(), IN_TYPE()}, OUT_TYPE(), \ - kResultNullIfNull, ARROW_STRINGIFY(NAME##_##IN_TYPE##_##IN_TYPE), \ +#define BINARY_UNSAFE_NULL_IF_NULL(NAME, ALIASES, IN_TYPE, OUT_TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{IN_TYPE(), IN_TYPE()}, OUT_TYPE(), kResultNullIfNull, \ + ARROW_STRINGIFY(NAME##_##IN_TYPE##_##IN_TYPE), \ NativeFunction::kNeedsContext | NativeFunction::kCanReturnErrors) -#define BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(NAME, TYPE) \ - BINARY_UNSAFE_NULL_IF_NULL(NAME, TYPE, TYPE) +#define BINARY_SYMMETRIC_UNSAFE_NULL_IF_NULL(NAME, ALIASES, TYPE) \ + BINARY_UNSAFE_NULL_IF_NULL(NAME, ALIASES, TYPE, TYPE) // Binary functions that : // - have different input types, or output type // - NULL handling is of type NULL_IF_NULL // // The pre-compiled fn name includes the base name & input type names. eg. mod_int64_int32 -#define BINARY_GENERIC_SAFE_NULL_IF_NULL(NAME, IN_TYPE1, IN_TYPE2, OUT_TYPE) \ - NativeFunction(#NAME, DataTypeVector{IN_TYPE1(), IN_TYPE2()}, OUT_TYPE(), \ - kResultNullIfNull, ARROW_STRINGIFY(NAME##_##IN_TYPE1##_##IN_TYPE2)) +#define BINARY_GENERIC_SAFE_NULL_IF_NULL(NAME, ALIASES, IN_TYPE1, IN_TYPE2, OUT_TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{IN_TYPE1(), IN_TYPE2()}, OUT_TYPE(), kResultNullIfNull, \ + ARROW_STRINGIFY(NAME##_##IN_TYPE1##_##IN_TYPE2)) // Binary functions that : // - have the same input type @@ -108,33 +112,34 @@ typedef std::unordered_map<const FunctionSignature*, const NativeFunction*, KeyH // // The pre-compiled fn name includes the base name & input type names. // eg. equal_int32_int32 -#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE(), TYPE()}, boolean(), kResultNullIfNull, \ +#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{TYPE(), TYPE()}, boolean(), kResultNullIfNull, \ ARROW_STRINGIFY(NAME##_##TYPE##_##TYPE)) // Unary functions that : // - NULL handling is of type NULL_IF_NULL // // The pre-compiled fn name includes the base name & input type name. eg. castFloat_int32 -#define UNARY_SAFE_NULL_IF_NULL(NAME, IN_TYPE, OUT_TYPE) \ - NativeFunction(#NAME, DataTypeVector{IN_TYPE()}, OUT_TYPE(), kResultNullIfNull, \ - ARROW_STRINGIFY(NAME##_##IN_TYPE)) +#define UNARY_SAFE_NULL_IF_NULL(NAME, ALIASES, IN_TYPE, OUT_TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{IN_TYPE()}, \ + OUT_TYPE(), kResultNullIfNull, ARROW_STRINGIFY(NAME##_##IN_TYPE)) // Unary functions that : // - NULL handling is of type NULL_NEVER // // The pre-compiled fn name includes the base name & input type name. eg. isnull_int32 -#define UNARY_SAFE_NULL_NEVER_BOOL(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE()}, boolean(), kResultNullNever, \ - ARROW_STRINGIFY(NAME##_##TYPE)) +#define UNARY_SAFE_NULL_NEVER_BOOL(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{TYPE()}, \ + boolean(), kResultNullNever, ARROW_STRINGIFY(NAME##_##TYPE)) // Unary functions that : // - NULL handling is of type NULL_INTERNAL // // The pre-compiled fn name includes the base name & input type name. eg. castFloat_int32 -#define UNARY_UNSAFE_NULL_IF_NULL(NAME, IN_TYPE, OUT_TYPE) \ - NativeFunction(#NAME, DataTypeVector{IN_TYPE()}, OUT_TYPE(), kResultNullIfNull, \ - ARROW_STRINGIFY(NAME##_##IN_TYPE), \ +#define UNARY_UNSAFE_NULL_IF_NULL(NAME, ALIASES, IN_TYPE, OUT_TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{IN_TYPE()}, \ + OUT_TYPE(), kResultNullIfNull, ARROW_STRINGIFY(NAME##_##IN_TYPE), \ NativeFunction::kNeedsContext | NativeFunction::kCanReturnErrors) // Binary functions that : @@ -142,76 +147,84 @@ typedef std::unordered_map<const FunctionSignature*, const NativeFunction*, KeyH // // The pre-compiled fn name includes the base name & input type names, // eg. is_distinct_from_int32_int32 -#define BINARY_SAFE_NULL_NEVER_BOOL(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE(), TYPE()}, boolean(), kResultNullNever, \ +#define BINARY_SAFE_NULL_NEVER_BOOL(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{TYPE(), TYPE()}, boolean(), kResultNullNever, \ ARROW_STRINGIFY(NAME##_##TYPE##_##TYPE)) // Extract functions (used with data/time types) that : // - NULL handling is of type NULL_IF_NULL // // The pre-compiled fn name includes the base name & input type name. eg. extractYear_date -#define EXTRACT_SAFE_NULL_IF_NULL(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE()}, int64(), kResultNullIfNull, \ - ARROW_STRINGIFY(NAME##_##TYPE)) +#define EXTRACT_SAFE_NULL_IF_NULL(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{TYPE()}, \ + int64(), kResultNullIfNull, ARROW_STRINGIFY(NAME##_##TYPE)) // Hash32 functions that : // - NULL handling is of type NULL_NEVER // // The pre-compiled fn name includes the base name & input type name. hash32_int8 -#define HASH32_SAFE_NULL_NEVER(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE()}, int32(), kResultNullNever, \ - ARROW_STRINGIFY(NAME##_##TYPE)) +#define HASH32_SAFE_NULL_NEVER(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{TYPE()}, \ + int32(), kResultNullNever, ARROW_STRINGIFY(NAME##_##TYPE)) // Hash32 functions that : // - NULL handling is of type NULL_NEVER // // The pre-compiled fn name includes the base name & input type name. hash32_int8 -#define HASH64_SAFE_NULL_NEVER(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE()}, int64(), kResultNullNever, \ - ARROW_STRINGIFY(NAME##_##TYPE)) +#define HASH64_SAFE_NULL_NEVER(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, DataTypeVector{TYPE()}, \ + int64(), kResultNullNever, ARROW_STRINGIFY(NAME##_##TYPE)) // Hash32 functions with seed that : // - NULL handling is of type NULL_NEVER // // The pre-compiled fn name includes the base name & input type name. hash32WithSeed_int8 -#define HASH32_SEED_SAFE_NULL_NEVER(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE(), int32()}, int32(), kResultNullNever, \ +#define HASH32_SEED_SAFE_NULL_NEVER(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{TYPE(), int32()}, int32(), kResultNullNever, \ ARROW_STRINGIFY(NAME##WithSeed_##TYPE)) // Hash64 functions with seed that : // - NULL handling is of type NULL_NEVER // // The pre-compiled fn name includes the base name & input type name. hash32WithSeed_int8 -#define HASH64_SEED_SAFE_NULL_NEVER(NAME, TYPE) \ - NativeFunction(#NAME, DataTypeVector{TYPE(), int64()}, int64(), kResultNullNever, \ +#define HASH64_SEED_SAFE_NULL_NEVER(NAME, ALIASES, TYPE) \ + NativeFunction(#NAME, std::vector<std::string> ALIASES, \ + DataTypeVector{TYPE(), int64()}, int64(), kResultNullNever, \ ARROW_STRINGIFY(NAME##WithSeed_##TYPE)) // Iterate the inner macro over all numeric types -#define NUMERIC_TYPES(INNER, NAME) \ - INNER(NAME, int8), INNER(NAME, int16), INNER(NAME, int32), INNER(NAME, int64), \ - INNER(NAME, uint8), INNER(NAME, uint16), INNER(NAME, uint32), INNER(NAME, uint64), \ - INNER(NAME, float32), INNER(NAME, float64), INNER(NAME, decimal128) +#define NUMERIC_TYPES(INNER, NAME, ALIASES) \ + INNER(NAME, ALIASES, int8), INNER(NAME, ALIASES, int16), INNER(NAME, ALIASES, int32), \ + INNER(NAME, ALIASES, int64), INNER(NAME, ALIASES, uint8), \ + INNER(NAME, ALIASES, uint16), INNER(NAME, ALIASES, uint32), \ + INNER(NAME, ALIASES, uint64), INNER(NAME, ALIASES, float32), \ + INNER(NAME, ALIASES, float64), INNER(NAME, ALIASES, decimal128) // Iterate the inner macro over numeric and date/time types -#define NUMERIC_DATE_TYPES(INNER, NAME) \ - NUMERIC_TYPES(INNER, NAME), DATE_TYPES(INNER, NAME), TIME_TYPES(INNER, NAME) +#define NUMERIC_DATE_TYPES(INNER, NAME, ALIASES) \ + NUMERIC_TYPES(INNER, NAME, ALIASES), DATE_TYPES(INNER, NAME, ALIASES), \ + TIME_TYPES(INNER, NAME, ALIASES) // Iterate the inner macro over all date types -#define DATE_TYPES(INNER, NAME) INNER(NAME, date64), INNER(NAME, timestamp) +#define DATE_TYPES(INNER, NAME, ALIASES) \ + INNER(NAME, ALIASES, date64), INNER(NAME, ALIASES, timestamp) // Iterate the inner macro over all time types -#define TIME_TYPES(INNER, NAME) INNER(NAME, time32) +#define TIME_TYPES(INNER, NAME, ALIASES) INNER(NAME, ALIASES, time32) // Iterate the inner macro over all data types -#define VAR_LEN_TYPES(INNER, NAME) INNER(NAME, utf8), INNER(NAME, binary) +#define VAR_LEN_TYPES(INNER, NAME, ALIASES) \ + INNER(NAME, ALIASES, utf8), INNER(NAME, ALIASES, binary) // Iterate the inner macro over all numeric types, date types and bool type -#define NUMERIC_BOOL_DATE_TYPES(INNER, NAME) \ - NUMERIC_DATE_TYPES(INNER, NAME), INNER(NAME, boolean) +#define NUMERIC_BOOL_DATE_TYPES(INNER, NAME, ALIASES) \ + NUMERIC_DATE_TYPES(INNER, NAME, ALIASES), INNER(NAME, ALIASES, boolean) // Iterate the inner macro over all numeric types, date types, bool and varlen types -#define NUMERIC_BOOL_DATE_VAR_LEN_TYPES(INNER, NAME) \ - NUMERIC_BOOL_DATE_TYPES(INNER, NAME), VAR_LEN_TYPES(INNER, NAME) +#define NUMERIC_BOOL_DATE_VAR_LEN_TYPES(INNER, NAME, ALIASES) \ + NUMERIC_BOOL_DATE_TYPES(INNER, NAME, ALIASES), VAR_LEN_TYPES(INNER, NAME, ALIASES) } // namespace gandiva diff --git a/cpp/src/gandiva/function_registry_datetime.cc b/cpp/src/gandiva/function_registry_datetime.cc index f36e567..2f52b74 100644 --- a/cpp/src/gandiva/function_registry_datetime.cc +++ b/cpp/src/gandiva/function_registry_datetime.cc @@ -20,44 +20,44 @@ namespace gandiva { -#define DATE_EXTRACTION_FNS(name) \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Millennium), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Century), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Decade), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Year), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Quarter), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Month), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Week), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Day), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Hour), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Minute), \ - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Second) +#define DATE_EXTRACTION_FNS(name) \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Millennium, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Century, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Decade, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Year, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Quarter, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Month, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Week, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Day, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Hour, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Minute, {}), \ + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Second, {}) -#define TIME_EXTRACTION_FNS(name) \ - TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Hour), \ - TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Minute), \ - TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Second) +#define TIME_EXTRACTION_FNS(name) \ + TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Hour, {}), \ + TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Minute, {}), \ + TIME_TYPES(EXTRACT_SAFE_NULL_IF_NULL, name##Second, {}) std::vector<NativeFunction> GetDateTimeFunctionRegistry() { static std::vector<NativeFunction> date_time_fn_registry_ = { DATE_EXTRACTION_FNS(extract), DATE_EXTRACTION_FNS(date_trunc_), - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractDoy), - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractDow), - DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractEpoch), + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractDoy, {}), + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractDow, {}), + DATE_TYPES(EXTRACT_SAFE_NULL_IF_NULL, extractEpoch, {}), TIME_EXTRACTION_FNS(extract), - NativeFunction("castDATE", DataTypeVector{utf8()}, date64(), kResultNullIfNull, + NativeFunction("castDATE", {}, DataTypeVector{utf8()}, date64(), kResultNullIfNull, "castDATE_utf8", NativeFunction::kNeedsContext | NativeFunction::kCanReturnErrors), - NativeFunction("castTIMESTAMP", DataTypeVector{utf8()}, timestamp(), + NativeFunction("castTIMESTAMP", {}, DataTypeVector{utf8()}, timestamp(), kResultNullIfNull, "castTIMESTAMP_utf8", NativeFunction::kNeedsContext | NativeFunction::kCanReturnErrors), - NativeFunction("to_date", DataTypeVector{utf8(), utf8(), int32()}, date64(), + NativeFunction("to_date", {}, DataTypeVector{utf8(), utf8(), int32()}, date64(), kResultNullInternal, "gdv_fn_to_date_utf8_utf8_int32", NativeFunction::kNeedsContext | NativeFunction::kNeedsFunctionHolder | diff --git a/cpp/src/gandiva/function_registry_hash.cc b/cpp/src/gandiva/function_registry_hash.cc index a163a23..4184f50 100644 --- a/cpp/src/gandiva/function_registry_hash.cc +++ b/cpp/src/gandiva/function_registry_hash.cc @@ -20,32 +20,32 @@ namespace gandiva { -#define HASH32_SAFE_NULL_NEVER_FN(name) \ - NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH32_SAFE_NULL_NEVER, name) +#define HASH32_SAFE_NULL_NEVER_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH32_SAFE_NULL_NEVER, name, ALIASES) -#define HASH32_SEED_SAFE_NULL_NEVER_FN(name) \ - NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH32_SEED_SAFE_NULL_NEVER, name) +#define HASH32_SEED_SAFE_NULL_NEVER_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH32_SEED_SAFE_NULL_NEVER, name, ALIASES) -#define HASH64_SAFE_NULL_NEVER_FN(name) \ - NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH64_SAFE_NULL_NEVER, name) +#define HASH64_SAFE_NULL_NEVER_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH64_SAFE_NULL_NEVER, name, ALIASES) -#define HASH64_SEED_SAFE_NULL_NEVER_FN(name) \ - NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH64_SEED_SAFE_NULL_NEVER, name) +#define HASH64_SEED_SAFE_NULL_NEVER_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_VAR_LEN_TYPES(HASH64_SEED_SAFE_NULL_NEVER, name, ALIASES) std::vector<NativeFunction> GetHashFunctionRegistry() { static std::vector<NativeFunction> hash_fn_registry_ = { - HASH32_SAFE_NULL_NEVER_FN(hash), - HASH32_SAFE_NULL_NEVER_FN(hash32), - HASH32_SAFE_NULL_NEVER_FN(hash32AsDouble), + HASH32_SAFE_NULL_NEVER_FN(hash, {}), + HASH32_SAFE_NULL_NEVER_FN(hash32, {}), + HASH32_SAFE_NULL_NEVER_FN(hash32AsDouble, {}), - HASH32_SEED_SAFE_NULL_NEVER_FN(hash32), - HASH32_SEED_SAFE_NULL_NEVER_FN(hash32AsDouble), + HASH32_SEED_SAFE_NULL_NEVER_FN(hash32, {}), + HASH32_SEED_SAFE_NULL_NEVER_FN(hash32AsDouble, {}), - HASH64_SAFE_NULL_NEVER_FN(hash64), - HASH64_SAFE_NULL_NEVER_FN(hash64AsDouble), + HASH64_SAFE_NULL_NEVER_FN(hash64, {}), + HASH64_SAFE_NULL_NEVER_FN(hash64AsDouble, {}), - HASH64_SEED_SAFE_NULL_NEVER_FN(hash64), - HASH64_SEED_SAFE_NULL_NEVER_FN(hash64AsDouble)}; + HASH64_SEED_SAFE_NULL_NEVER_FN(hash64, {}), + HASH64_SEED_SAFE_NULL_NEVER_FN(hash64AsDouble, {})}; return hash_fn_registry_; } diff --git a/cpp/src/gandiva/function_registry_math_ops.cc b/cpp/src/gandiva/function_registry_math_ops.cc index 2084b7b..046556b 100644 --- a/cpp/src/gandiva/function_registry_math_ops.cc +++ b/cpp/src/gandiva/function_registry_math_ops.cc @@ -20,55 +20,56 @@ namespace gandiva { -#define MATH_UNARY_OPS(name) \ - UNARY_SAFE_NULL_IF_NULL(name, int32, float64), \ - UNARY_SAFE_NULL_IF_NULL(name, int64, float64), \ - UNARY_SAFE_NULL_IF_NULL(name, uint32, float64), \ - UNARY_SAFE_NULL_IF_NULL(name, uint64, float64), \ - UNARY_SAFE_NULL_IF_NULL(name, float32, float64), \ - UNARY_SAFE_NULL_IF_NULL(name, float64, float64) +#define MATH_UNARY_OPS(name, ALIASES) \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int32, float64), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int64, float64), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint32, float64), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint64, float64), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float32, float64), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float64, float64) -#define MATH_BINARY_UNSAFE(name) \ - BINARY_UNSAFE_NULL_IF_NULL(name, int32, float64), \ - BINARY_UNSAFE_NULL_IF_NULL(name, int64, float64), \ - BINARY_UNSAFE_NULL_IF_NULL(name, uint32, float64), \ - BINARY_UNSAFE_NULL_IF_NULL(name, uint64, float64), \ - BINARY_UNSAFE_NULL_IF_NULL(name, float32, float64), \ - BINARY_UNSAFE_NULL_IF_NULL(name, float64, float64) +#define MATH_BINARY_UNSAFE(name, ALIASES) \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, int32, float64), \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, int64, float64), \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, uint32, float64), \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, uint64, float64), \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, float32, float64), \ + BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, float64, float64) -#define UNARY_SAFE_NULL_NEVER_BOOL_FN(name) \ - NUMERIC_BOOL_DATE_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, name) +#define UNARY_SAFE_NULL_NEVER_BOOL_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, name, ALIASES) -#define BINARY_SAFE_NULL_NEVER_BOOL_FN(name) \ - NUMERIC_BOOL_DATE_TYPES(BINARY_SAFE_NULL_NEVER_BOOL, name) +#define BINARY_SAFE_NULL_NEVER_BOOL_FN(name, ALIASES) \ + NUMERIC_BOOL_DATE_TYPES(BINARY_SAFE_NULL_NEVER_BOOL, name, ALIASES) std::vector<NativeFunction> GetMathOpsFunctionRegistry() { static std::vector<NativeFunction> math_fn_registry_ = { - MATH_UNARY_OPS(cbrt), - MATH_UNARY_OPS(exp), - MATH_UNARY_OPS(log), - MATH_UNARY_OPS(log10), + MATH_UNARY_OPS(cbrt, {}), + MATH_UNARY_OPS(exp, {}), + MATH_UNARY_OPS(log, {}), + MATH_UNARY_OPS(log10, {}), - MATH_BINARY_UNSAFE(log), + MATH_BINARY_UNSAFE(log, {}), - BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(power, float64), + BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(power, {"pow"}, float64), - UNARY_SAFE_NULL_NEVER_BOOL_FN(isnull), - UNARY_SAFE_NULL_NEVER_BOOL_FN(isnotnull), + UNARY_SAFE_NULL_NEVER_BOOL_FN(isnull, {}), + UNARY_SAFE_NULL_NEVER_BOOL_FN(isnotnull, {}), - NUMERIC_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, isnumeric), + NUMERIC_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, isnumeric, {}), - BINARY_SAFE_NULL_NEVER_BOOL_FN(is_distinct_from), - BINARY_SAFE_NULL_NEVER_BOOL_FN(is_not_distinct_from), + BINARY_SAFE_NULL_NEVER_BOOL_FN(is_distinct_from, {}), + BINARY_SAFE_NULL_NEVER_BOOL_FN(is_not_distinct_from, {}), // decimal functions - UNARY_SAFE_NULL_IF_NULL(abs, decimal128, decimal128), - UNARY_SAFE_NULL_IF_NULL(ceil, decimal128, decimal128), - UNARY_SAFE_NULL_IF_NULL(floor, decimal128, decimal128), - UNARY_SAFE_NULL_IF_NULL(round, decimal128, decimal128), - UNARY_SAFE_NULL_IF_NULL(truncate, decimal128, decimal128), - BINARY_GENERIC_SAFE_NULL_IF_NULL(round, decimal128, int32, decimal128), - BINARY_GENERIC_SAFE_NULL_IF_NULL(truncate, decimal128, int32, decimal128), + UNARY_SAFE_NULL_IF_NULL(abs, {}, decimal128, decimal128), + UNARY_SAFE_NULL_IF_NULL(ceil, {}, decimal128, decimal128), + UNARY_SAFE_NULL_IF_NULL(floor, {}, decimal128, decimal128), + UNARY_SAFE_NULL_IF_NULL(round, {}, decimal128, decimal128), + UNARY_SAFE_NULL_IF_NULL(truncate, {"trunc"}, decimal128, decimal128), + BINARY_GENERIC_SAFE_NULL_IF_NULL(round, {}, decimal128, int32, decimal128), + BINARY_GENERIC_SAFE_NULL_IF_NULL(truncate, {"trunc"}, decimal128, int32, + decimal128), }; return math_fn_registry_; diff --git a/cpp/src/gandiva/function_registry_string.cc b/cpp/src/gandiva/function_registry_string.cc index af1f37f..bd2fe18 100644 --- a/cpp/src/gandiva/function_registry_string.cc +++ b/cpp/src/gandiva/function_registry_string.cc @@ -20,53 +20,55 @@ namespace gandiva { -#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(name) \ - VAR_LEN_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name) +#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(name, ALIASES) \ + VAR_LEN_TYPES(BINARY_RELATIONAL_SAFE_NULL_IF_NULL, name, ALIASES) -#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(name) \ - BINARY_RELATIONAL_SAFE_NULL_IF_NULL(name, utf8) +#define BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(name, ALIASES) \ + BINARY_RELATIONAL_SAFE_NULL_IF_NULL(name, ALIASES, utf8) -#define UNARY_OCTET_LEN_FN(name) \ - UNARY_SAFE_NULL_IF_NULL(name, utf8, int32), UNARY_SAFE_NULL_IF_NULL(name, binary, int32) +#define UNARY_OCTET_LEN_FN(name, ALIASES) \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, utf8, int32), \ + UNARY_SAFE_NULL_IF_NULL(name, ALIASES, binary, int32) -#define UNARY_SAFE_NULL_NEVER_BOOL_FN(name) \ - VAR_LEN_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, name) +#define UNARY_SAFE_NULL_NEVER_BOOL_FN(name, ALIASES) \ + VAR_LEN_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, name, ALIASES) std::vector<NativeFunction> GetStringFunctionRegistry() { static std::vector<NativeFunction> string_fn_registry_ = { - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(equal), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(not_equal), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(less_than), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(less_than_or_equal_to), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(greater_than), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(greater_than_or_equal_to), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(equal, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(not_equal, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(less_than, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(less_than_or_equal_to, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(greater_than, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_FN(greater_than_or_equal_to, {}), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(starts_with), - BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(ends_with), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(starts_with, {}), + BINARY_RELATIONAL_SAFE_NULL_IF_NULL_UTF8_FN(ends_with, {}), - UNARY_OCTET_LEN_FN(octet_length), - UNARY_OCTET_LEN_FN(bit_length), + UNARY_OCTET_LEN_FN(octet_length, {}), + UNARY_OCTET_LEN_FN(bit_length, {}), - UNARY_UNSAFE_NULL_IF_NULL(char_length, utf8, int32), - UNARY_UNSAFE_NULL_IF_NULL(length, utf8, int32), - UNARY_UNSAFE_NULL_IF_NULL(lengthUtf8, binary, int32), + UNARY_UNSAFE_NULL_IF_NULL(char_length, {}, utf8, int32), + UNARY_UNSAFE_NULL_IF_NULL(length, {}, utf8, int32), + UNARY_UNSAFE_NULL_IF_NULL(lengthUtf8, {}, binary, int32), - UNARY_SAFE_NULL_NEVER_BOOL_FN(isnull), - UNARY_SAFE_NULL_NEVER_BOOL_FN(isnotnull), + UNARY_SAFE_NULL_NEVER_BOOL_FN(isnull, {}), + UNARY_SAFE_NULL_NEVER_BOOL_FN(isnotnull, {}), - NativeFunction("upper", DataTypeVector{utf8()}, utf8(), kResultNullIfNull, + NativeFunction("upper", {}, DataTypeVector{utf8()}, utf8(), kResultNullIfNull, "upper_utf8", NativeFunction::kNeedsContext), - NativeFunction("castVARCHAR", DataTypeVector{utf8(), int64()}, utf8(), + NativeFunction("castVARCHAR", {}, DataTypeVector{utf8(), int64()}, utf8(), kResultNullIfNull, "castVARCHAR_utf8_int64", NativeFunction::kNeedsContext), - NativeFunction("castVARCHAR", DataTypeVector{decimal128(), int64()}, utf8(), + NativeFunction("castVARCHAR", {}, DataTypeVector{decimal128(), int64()}, utf8(), kResultNullIfNull, "castVARCHAR_decimal128_int64", NativeFunction::kNeedsContext), - NativeFunction("like", DataTypeVector{utf8(), utf8()}, boolean(), kResultNullIfNull, - "gdv_fn_like_utf8_utf8", NativeFunction::kNeedsFunctionHolder)}; + NativeFunction("like", {}, DataTypeVector{utf8(), utf8()}, boolean(), + kResultNullIfNull, "gdv_fn_like_utf8_utf8", + NativeFunction::kNeedsFunctionHolder)}; return string_fn_registry_; } diff --git a/cpp/src/gandiva/function_registry_test.cc b/cpp/src/gandiva/function_registry_test.cc index 247d13e..6d96d79 100644 --- a/cpp/src/gandiva/function_registry_test.cc +++ b/cpp/src/gandiva/function_registry_test.cc @@ -17,6 +17,7 @@ #include "gandiva/function_registry.h" +#include <gmock/gmock.h> #include <gtest/gtest.h> namespace gandiva { @@ -31,7 +32,7 @@ TEST_F(TestFunctionRegistry, TestFound) { const NativeFunction* function = registry_.LookupSignature(add_i32_i32); EXPECT_NE(function, nullptr); - EXPECT_EQ(function->signature(), add_i32_i32); + EXPECT_THAT(function->signatures(), testing::Contains(add_i32_i32)); EXPECT_EQ(function->pc_name(), "add_int32_int32"); } diff --git a/cpp/src/gandiva/function_registry_timestamp_arithmetic.cc b/cpp/src/gandiva/function_registry_timestamp_arithmetic.cc index 7587212..b9d41ea 100644 --- a/cpp/src/gandiva/function_registry_timestamp_arithmetic.cc +++ b/cpp/src/gandiva/function_registry_timestamp_arithmetic.cc @@ -20,60 +20,60 @@ namespace gandiva { -#define TIMESTAMP_ADD_FNS(name) \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, timestamp, timestamp), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, date64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, timestamp, timestamp), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, date64, date64) +#define TIMESTAMP_ADD_FNS(name, ALIASES) \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, timestamp, timestamp), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, date64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, timestamp, timestamp), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, date64, date64) -#define TIMESTAMP_DIFF_FN(name) \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, timestamp, timestamp, int32) +#define TIMESTAMP_DIFF_FN(name, ALIASES) \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, timestamp, timestamp, int32) -#define DATE_ADD_FNS(name) \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, date64, int32, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, timestamp, int32, timestamp), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, date64, int64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, timestamp, int64, timestamp), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, date64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, timestamp, timestamp), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, date64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, timestamp, timestamp) +#define DATE_ADD_FNS(name, ALIASES) \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, date64, int32, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, timestamp, int32, timestamp), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, date64, int64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, timestamp, int64, timestamp), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, date64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, timestamp, timestamp), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, date64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, timestamp, timestamp) -#define DATE_DIFF_FNS(name) \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, date64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int32, timestamp, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, date64, date64), \ - BINARY_GENERIC_SAFE_NULL_IF_NULL(name, int64, timestamp, date64) +#define DATE_DIFF_FNS(name, ALIASES) \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, date64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, timestamp, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, date64, date64), \ + BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, timestamp, date64) std::vector<NativeFunction> GetDateTimeArithmeticFunctionRegistry() { static std::vector<NativeFunction> datetime_fn_registry_ = { - BINARY_GENERIC_SAFE_NULL_IF_NULL(months_between, date64, date64, float64), - BINARY_GENERIC_SAFE_NULL_IF_NULL(months_between, timestamp, timestamp, float64), + BINARY_GENERIC_SAFE_NULL_IF_NULL(months_between, {}, date64, date64, float64), + BINARY_GENERIC_SAFE_NULL_IF_NULL(months_between, {}, timestamp, timestamp, float64), - TIMESTAMP_DIFF_FN(timestampdiffSecond), - TIMESTAMP_DIFF_FN(timestampdiffMinute), - TIMESTAMP_DIFF_FN(timestampdiffHour), - TIMESTAMP_DIFF_FN(timestampdiffDay), - TIMESTAMP_DIFF_FN(timestampdiffWeek), - TIMESTAMP_DIFF_FN(timestampdiffMonth), - TIMESTAMP_DIFF_FN(timestampdiffQuarter), - TIMESTAMP_DIFF_FN(timestampdiffYear), + TIMESTAMP_DIFF_FN(timestampdiffSecond, {}), + TIMESTAMP_DIFF_FN(timestampdiffMinute, {}), + TIMESTAMP_DIFF_FN(timestampdiffHour, {}), + TIMESTAMP_DIFF_FN(timestampdiffDay, {}), + TIMESTAMP_DIFF_FN(timestampdiffWeek, {}), + TIMESTAMP_DIFF_FN(timestampdiffMonth, {}), + TIMESTAMP_DIFF_FN(timestampdiffQuarter, {}), + TIMESTAMP_DIFF_FN(timestampdiffYear, {}), - TIMESTAMP_ADD_FNS(timestampaddSecond), - TIMESTAMP_ADD_FNS(timestampaddMinute), - TIMESTAMP_ADD_FNS(timestampaddHour), - TIMESTAMP_ADD_FNS(timestampaddDay), - TIMESTAMP_ADD_FNS(timestampaddWeek), - TIMESTAMP_ADD_FNS(timestampaddMonth), - TIMESTAMP_ADD_FNS(timestampaddQuarter), - TIMESTAMP_ADD_FNS(timestampaddYear), + TIMESTAMP_ADD_FNS(timestampaddSecond, {}), + TIMESTAMP_ADD_FNS(timestampaddMinute, {}), + TIMESTAMP_ADD_FNS(timestampaddHour, {}), + TIMESTAMP_ADD_FNS(timestampaddDay, {}), + TIMESTAMP_ADD_FNS(timestampaddWeek, {}), + TIMESTAMP_ADD_FNS(timestampaddMonth, {}), + TIMESTAMP_ADD_FNS(timestampaddQuarter, {}), + TIMESTAMP_ADD_FNS(timestampaddYear, {}), - DATE_ADD_FNS(date_add), - DATE_ADD_FNS(add), + DATE_ADD_FNS(date_add, {}), + DATE_ADD_FNS(add, {}), - DATE_DIFF_FNS(date_sub), - DATE_DIFF_FNS(subtract), - DATE_DIFF_FNS(date_diff)}; + DATE_DIFF_FNS(date_sub, {}), + DATE_DIFF_FNS(subtract, {}), + DATE_DIFF_FNS(date_diff, {})}; return datetime_fn_registry_; } diff --git a/cpp/src/gandiva/native_function.h b/cpp/src/gandiva/native_function.h index 82714c7..540e07b 100644 --- a/cpp/src/gandiva/native_function.h +++ b/cpp/src/gandiva/native_function.h @@ -45,7 +45,7 @@ class GANDIVA_EXPORT NativeFunction { static constexpr int32_t kNeedsFunctionHolder = (1 << 2); static constexpr int32_t kCanReturnErrors = (1 << 3); - const FunctionSignature& signature() const { return signature_; } + const std::vector<FunctionSignature>& signatures() const { return signatures_; } std::string pc_name() const { return pc_name_; } ResultNullableType result_nullable_type() const { return result_nullable_type_; } @@ -53,16 +53,22 @@ class GANDIVA_EXPORT NativeFunction { bool NeedsFunctionHolder() const { return (flags_ & kNeedsFunctionHolder) != 0; } bool CanReturnErrors() const { return (flags_ & kCanReturnErrors) != 0; } - NativeFunction(const std::string& base_name, const DataTypeVector& param_types, - DataTypePtr ret_type, const ResultNullableType& result_nullable_type, + NativeFunction(const std::string& base_name, const std::vector<std::string>& aliases, + const DataTypeVector& param_types, DataTypePtr ret_type, + const ResultNullableType& result_nullable_type, const std::string& pc_name, int32_t flags = 0) - : signature_(base_name, param_types, ret_type), + : signatures_(), flags_(flags), result_nullable_type_(result_nullable_type), - pc_name_(pc_name) {} + pc_name_(pc_name) { + signatures_.push_back(FunctionSignature(base_name, param_types, ret_type)); + for (auto& func_name : aliases) { + signatures_.push_back(FunctionSignature(func_name, param_types, ret_type)); + } + } private: - FunctionSignature signature_; + std::vector<FunctionSignature> signatures_; /// attributes int32_t flags_; diff --git a/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ExpressionRegistryTest.java b/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ExpressionRegistryTest.java index 63a7536..99ae5e4 100644 --- a/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ExpressionRegistryTest.java +++ b/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ExpressionRegistryTest.java @@ -43,4 +43,14 @@ public class ExpressionRegistryTest { Set<FunctionSignature> functions = ExpressionRegistry.getInstance().getSupportedFunctions(); Assert.assertTrue(functions.contains(signature)); } + + @Test + public void testFunctionAliases() throws GandivaException { + ArrowType.Int int64 = new ArrowType.Int(64, true); + FunctionSignature signature = + new FunctionSignature("modulo", int64, Lists.newArrayList(int64, int64)); + Set<FunctionSignature> functions = ExpressionRegistry.getInstance().getSupportedFunctions(); + Assert.assertTrue(functions.contains(signature)); + } + }