You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ra...@apache.org on 2019/07/12 11:58:35 UTC

[arrow] branch master updated: ARROW-5892 : [C++][Gandiva] Support function aliases

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 <pr...@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 <pr...@icloud.com>
    Author: pprudhvi <30...@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));
+  }
+
 }