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/08 09:59:12 UTC

[arrow] branch master updated: ARROW-5867: [C++][Gandiva] add support for cast int to decimal

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 49ed11b  ARROW-5867: [C++][Gandiva] add support for cast int to decimal
49ed11b is described below

commit 49ed11b7d161666952bddb6aace76f0c06c26f98
Author: Pindikura Ravindra <ra...@dremio.com>
AuthorDate: Mon Jul 8 15:28:55 2019 +0530

    ARROW-5867: [C++][Gandiva] add support for cast int to decimal
    
    - cleanup and remove indirection for decimal fns
    - add fn for casting int/float to decimal
    
    Author: Pindikura Ravindra <ra...@dremio.com>
    
    Closes #4817 from pravindra/int2dec and squashes the following commits:
    
    c80ee0044 <Pindikura Ravindra> fix format
    3a5e7530d <Pindikura Ravindra> add fns for casting int/float to decimal
    768dcd106 <Pindikura Ravindra> ARROW-5867: add support for cast int to decimal
---
 cpp/src/gandiva/decimal_ir.cc                   | 466 +++---------------------
 cpp/src/gandiva/decimal_ir.h                    |   4 +
 cpp/src/gandiva/function_registry_arithmetic.cc |   2 +
 cpp/src/gandiva/gdv_function_stubs.cc           |   4 +-
 cpp/src/gandiva/llvm_generator.cc               |  15 +-
 cpp/src/gandiva/precompiled/decimal_wrapper.cc  | 221 +++++------
 cpp/src/gandiva/tests/decimal_test.cc           |  34 +-
 7 files changed, 208 insertions(+), 538 deletions(-)

diff --git a/cpp/src/gandiva/decimal_ir.cc b/cpp/src/gandiva/decimal_ir.cc
index 463e448..d9ea4e0 100644
--- a/cpp/src/gandiva/decimal_ir.cc
+++ b/cpp/src/gandiva/decimal_ir.cc
@@ -16,6 +16,7 @@
 // under the License.
 
 #include <sstream>
+#include <unordered_set>
 #include <utility>
 
 #include "arrow/status.h"
@@ -35,6 +36,21 @@ namespace gandiva {
     AddTrace128(msg, value);      \
   }
 
+// These are the functions defined in this file. The rest are in precompiled folder,
+// and the i128 needs to be dis-assembled for those.
+static const char* kAddFunction = "add_decimal128_decimal128";
+static const char* kSubtractFunction = "subtract_decimal128_decimal128";
+static const char* kEQFunction = "equal_decimal128_decimal128";
+static const char* kNEFunction = "not_equal_decimal128_decimal128";
+static const char* kLTFunction = "less_than_decimal128_decimal128";
+static const char* kLEFunction = "less_than_or_equal_to_decimal128_decimal128";
+static const char* kGTFunction = "greater_than_decimal128_decimal128";
+static const char* kGEFunction = "greater_than_or_equal_to_decimal128_decimal128";
+
+static const std::unordered_set<std::string> kDecimalIRBuilderFunctions{
+    kAddFunction, kSubtractFunction, kEQFunction, kNEFunction,
+    kLTFunction,  kLEFunction,       kGTFunction, kGEFunction};
+
 const char* DecimalIR::kScaleMultipliersName = "gandivaScaleMultipliers";
 
 /// Populate globals required by decimal IR.
@@ -250,7 +266,7 @@ Status DecimalIR::BuildAdd() {
   //                           int32_t out_precision, int32_t out_scale)
   auto i32 = types()->i32_type();
   auto i128 = types()->i128_type();
-  auto function = BuildFunction("add_decimal128_decimal128", i128,
+  auto function = BuildFunction(kAddFunction, i128,
                                 {
                                     {"x_value", i128},
                                     {"x_precision", i32},
@@ -316,7 +332,7 @@ Status DecimalIR::BuildSubtract() {
   //                           int32_t out_precision, int32_t out_scale)
   auto i32 = types()->i32_type();
   auto i128 = types()->i128_type();
-  auto function = BuildFunction("subtract_decimal128_decimal128", i128,
+  auto function = BuildFunction(kSubtractFunction, i128,
                                 {
                                     {"x_value", i128},
                                     {"x_precision", i32},
@@ -345,121 +361,13 @@ Status DecimalIR::BuildSubtract() {
     }
     ++i;
   }
-  auto value =
-      ir_builder()->CreateCall(module()->getFunction("add_decimal128_decimal128"), args);
+  auto value = ir_builder()->CreateCall(module()->getFunction(kAddFunction), args);
 
   // store result to out
   ir_builder()->CreateRet(value);
   return Status::OK();
 }
 
-Status DecimalIR::BuildMultiply() {
-  // Create fn prototype :
-  // int128_t
-  // multiply_decimal128_decimal128(int128_t x_value, int32_t x_precision, int32_t
-  // x_scale,
-  //                           int128_t y_value, int32_t y_precision, int32_t y_scale
-  //                           int32_t out_precision, int32_t out_scale)
-  auto i32 = types()->i32_type();
-  auto i128 = types()->i128_type();
-  auto function = BuildFunction("multiply_decimal128_decimal128", i128,
-                                {
-                                    {"x_value", i128},
-                                    {"x_precision", i32},
-                                    {"x_scale", i32},
-                                    {"y_value", i128},
-                                    {"y_precision", i32},
-                                    {"y_scale", i32},
-                                    {"out_precision", i32},
-                                    {"out_scale", i32},
-                                });
-
-  auto arg_iter = function->arg_begin();
-  ValueFull x(&arg_iter[0], &arg_iter[1], &arg_iter[2]);
-  ValueFull y(&arg_iter[3], &arg_iter[4], &arg_iter[5]);
-  ValueFull out(nullptr, &arg_iter[6], &arg_iter[7]);
-
-  auto entry = llvm::BasicBlock::Create(*context(), "entry", function);
-  ir_builder()->SetInsertPoint(entry);
-
-  // Make call to pre-compiled IR function.
-  auto block = ir_builder()->GetInsertBlock();
-  auto out_high_ptr = new llvm::AllocaInst(types()->i64_type(), 0, "out_hi", block);
-  auto out_low_ptr = new llvm::AllocaInst(types()->i64_type(), 0, "out_low", block);
-  auto x_split = ValueSplit::MakeFromInt128(this, x.value());
-  auto y_split = ValueSplit::MakeFromInt128(this, y.value());
-
-  std::vector<llvm::Value*> args = {
-      x_split.high(),  x_split.low(), x.precision(), x.scale(),
-      y_split.high(),  y_split.low(), y.precision(), y.scale(),
-      out.precision(), out.scale(),   out_high_ptr,  out_low_ptr,
-  };
-  ir_builder()->CreateCall(
-      module()->getFunction("multiply_internal_decimal128_decimal128"), args);
-
-  auto out_high = ir_builder()->CreateLoad(out_high_ptr);
-  auto out_low = ir_builder()->CreateLoad(out_low_ptr);
-  auto result = ValueSplit(out_high, out_low).AsInt128(this);
-  ADD_TRACE_128("Multiply : result", result);
-
-  ir_builder()->CreateRet(result);
-  return Status::OK();
-}
-
-Status DecimalIR::BuildDivideOrMod(const std::string& function_name,
-                                   const std::string& internal_fname) {
-  // Create fn prototype :
-  // int128_t
-  // divide_decimal128_decimal128(int64_t execution_context,
-  //                              int128_t x_value, int32_t x_precision, int32_t x_scale,
-  //                              int128_t y_value, int32_t y_precision, int32_t y_scale
-  //                              int32_t out_precision, int32_t out_scale)
-  auto i32 = types()->i32_type();
-  auto i128 = types()->i128_type();
-  auto function = BuildFunction(function_name, i128,
-                                {
-                                    {"execution_context", types()->i64_type()},
-                                    {"x_value", i128},
-                                    {"x_precision", i32},
-                                    {"x_scale", i32},
-                                    {"y_value", i128},
-                                    {"y_precision", i32},
-                                    {"y_scale", i32},
-                                    {"out_precision", i32},
-                                    {"out_scale", i32},
-                                });
-
-  auto arg_iter = function->arg_begin();
-  auto execution_context = &arg_iter[0];
-  ValueFull x(&arg_iter[1], &arg_iter[2], &arg_iter[3]);
-  ValueFull y(&arg_iter[4], &arg_iter[5], &arg_iter[6]);
-  ValueFull out(nullptr, &arg_iter[7], &arg_iter[8]);
-
-  auto entry = llvm::BasicBlock::Create(*context(), "entry", function);
-  ir_builder()->SetInsertPoint(entry);
-
-  // Make call to pre-compiled IR function.
-  auto block = ir_builder()->GetInsertBlock();
-  auto out_high_ptr = new llvm::AllocaInst(types()->i64_type(), 0, "out_hi", block);
-  auto out_low_ptr = new llvm::AllocaInst(types()->i64_type(), 0, "out_low", block);
-  auto x_split = ValueSplit::MakeFromInt128(this, x.value());
-  auto y_split = ValueSplit::MakeFromInt128(this, y.value());
-
-  std::vector<llvm::Value*> args = {
-      execution_context, x_split.high(), x_split.low(), x.precision(), x.scale(),
-      y_split.high(),    y_split.low(),  y.precision(), y.scale(),     out.precision(),
-      out.scale(),       out_high_ptr,   out_low_ptr,
-  };
-  ir_builder()->CreateCall(module()->getFunction(internal_fname), args);
-
-  auto out_high = ir_builder()->CreateLoad(out_high_ptr);
-  auto out_low = ir_builder()->CreateLoad(out_low_ptr);
-  auto result = ValueSplit(out_high, out_low).AsInt128(this);
-
-  ir_builder()->CreateRet(result);
-  return Status::OK();
-}
-
 Status DecimalIR::BuildCompare(const std::string& function_name,
                                llvm::ICmpInst::Predicate cmp_instruction) {
   // Create fn prototype :
@@ -495,50 +403,47 @@ Status DecimalIR::BuildCompare(const std::string& function_name,
       y_split.high(), y_split.low(), y.precision(), y.scale(),
   };
   auto cmp_value = ir_builder()->CreateCall(
-      module()->getFunction("compare_internal_decimal128_decimal128"), args);
+      module()->getFunction("compare_decimal128_decimal128_internal"), args);
   auto result =
       ir_builder()->CreateICmp(cmp_instruction, cmp_value, types()->i32_constant(0));
   ir_builder()->CreateRet(result);
   return Status::OK();
 }
 
-Status DecimalIR::BuildDecimalFunction(const std::string& function_name,
-                                       llvm::Type* return_type,
-                                       std::vector<NamedArg> in_types) {
-  auto i64 = types()->i64_type();
-  auto i128 = types()->i128_type();
-  auto function = BuildFunction(function_name, return_type, in_types);
-
-  auto entry = llvm::BasicBlock::Create(*context(), "entry", function);
-  ir_builder()->SetInsertPoint(entry);
+llvm::Value* DecimalIR::CallDecimalFunction(const std::string& function_name,
+                                            llvm::Type* return_type,
+                                            const std::vector<llvm::Value*>& params) {
+  if (kDecimalIRBuilderFunctions.count(function_name) != 0) {
+    // this is fn built with the irbuilder.
+    return ir_builder()->CreateCall(module()->getFunction(function_name), params);
+  }
 
-  std::vector<llvm::Value*> args;
-  int arg_idx = 0;
-  auto arg_iter = function->arg_begin();
-  for (auto& type : in_types) {
-    if (type.type == i128) {
+  // ppre-compiler fn : disassemble i128 to two i64s and re-assemble.
+  auto i128 = types()->i128_type();
+  auto i64 = types()->i64_type();
+  std::vector<llvm::Value*> dis_assembled_args;
+  for (auto& arg : params) {
+    if (arg->getType() == i128) {
       // split i128 arg into two int64s.
-      auto split = ValueSplit::MakeFromInt128(this, &arg_iter[arg_idx]);
-      args.push_back(split.high());
-      args.push_back(split.low());
+      auto split = ValueSplit::MakeFromInt128(this, arg);
+      dis_assembled_args.push_back(split.high());
+      dis_assembled_args.push_back(split.low());
     } else {
-      args.push_back(&arg_iter[arg_idx]);
+      dis_assembled_args.push_back(arg);
     }
-    ++arg_idx;
   }
 
-  auto internal_name = function_name + "_internal";
   llvm::Value* result = nullptr;
   if (return_type == i128) {
     // for i128 ret, replace with two int64* args, and join them.
     auto block = ir_builder()->GetInsertBlock();
     auto out_high_ptr = new llvm::AllocaInst(i64, 0, "out_hi", block);
     auto out_low_ptr = new llvm::AllocaInst(i64, 0, "out_low", block);
-    args.push_back(out_high_ptr);
-    args.push_back(out_low_ptr);
+    dis_assembled_args.push_back(out_high_ptr);
+    dis_assembled_args.push_back(out_low_ptr);
 
     // Make call to pre-compiled IR function.
-    ir_builder()->CreateCall(module()->getFunction(internal_name), args);
+    ir_builder()->CreateCall(module()->getFunction(function_name), dis_assembled_args);
 
     auto out_high = ir_builder()->CreateLoad(out_high_ptr);
     auto out_low = ir_builder()->CreateLoad(out_low_ptr);
@@ -547,21 +452,14 @@ Status DecimalIR::BuildDecimalFunction(const std::string& function_name,
     DCHECK_NE(return_type, types()->void_type());
 
     // Make call to pre-compiled IR function.
-    result = ir_builder()->CreateCall(module()->getFunction(internal_name), args);
+    result = ir_builder()->CreateCall(module()->getFunction(function_name),
+                                      dis_assembled_args);
   }
-  ir_builder()->CreateRet(result);
-  return Status::OK();
+  return result;
 }
 
 Status DecimalIR::AddFunctions(Engine* engine) {
   auto decimal_ir = std::make_shared<DecimalIR>(engine);
-  auto i128 = decimal_ir->types()->i128_type();
-  auto i32 = decimal_ir->types()->i32_type();
-  auto i1 = decimal_ir->types()->i1_type();
-  auto i64 = decimal_ir->types()->i64_type();
-  auto f64 = decimal_ir->types()->double_type();
-  auto i8_ptr = decimal_ir->types()->i8_ptr_type();
-  auto i32_ptr = decimal_ir->types()->i32_ptr_type();
 
   // Populate global variables used by decimal operations.
   decimal_ir->AddGlobals(engine);
@@ -571,278 +469,12 @@ Status DecimalIR::AddFunctions(Engine* engine) {
 
   ARROW_RETURN_NOT_OK(decimal_ir->BuildAdd());
   ARROW_RETURN_NOT_OK(decimal_ir->BuildSubtract());
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildMultiply());
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDivideOrMod(
-      "divide_decimal128_decimal128", "divide_internal_decimal128_decimal128"));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDivideOrMod("mod_decimal128_decimal128",
-                                                   "mod_internal_decimal128_decimal128"));
-
-  ARROW_RETURN_NOT_OK(
-      decimal_ir->BuildCompare("equal_decimal128_decimal128", llvm::ICmpInst::ICMP_EQ));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare("not_equal_decimal128_decimal128",
-                                               llvm::ICmpInst::ICMP_NE));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare("less_than_decimal128_decimal128",
-                                               llvm::ICmpInst::ICMP_SLT));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(
-      "less_than_or_equal_to_decimal128_decimal128", llvm::ICmpInst::ICMP_SLE));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare("greater_than_decimal128_decimal128",
-                                               llvm::ICmpInst::ICMP_SGT));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(
-      "greater_than_or_equal_to_decimal128_decimal128", llvm::ICmpInst::ICMP_SGE));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("abs_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("ceil_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("floor_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("round_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("round_decimal128_int32", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"round_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("truncate_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("truncate_decimal128_int32", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"round_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castDECIMAL_int64", i128,
-                                                       {
-                                                           {"value", i64},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castDECIMAL_float64", i128,
-                                                       {
-                                                           {"value", f64},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castDECIMAL_decimal128", i128,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castBIGINT_decimal128", i64,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castFLOAT8_decimal128", f64,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash_decimal128", i32,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash32_decimal128", i32,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash64_decimal128", i64,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash32WithSeed_decimal128", i32,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                           {"seed", i32},
-                                                           {"seed_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash64WithSeed_decimal128", i64,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                           {"seed", i64},
-                                                           {"seed_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash32AsDouble_decimal128", i32,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("hash64AsDouble_decimal128", i64,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(
-      decimal_ir->BuildDecimalFunction("hash32AsDoubleWithSeed_decimal128", i32,
-                                       {
-                                           {"x_value", i128},
-                                           {"x_precision", i32},
-                                           {"x_scale", i32},
-                                           {"x_isvalid", i1},
-                                           {"seed", i32},
-                                           {"seed_isvalid", i1},
-                                       }));
-
-  ARROW_RETURN_NOT_OK(
-      decimal_ir->BuildDecimalFunction("hash64AsDoubleWithSeed_decimal128", i64,
-                                       {
-                                           {"x_value", i128},
-                                           {"x_precision", i32},
-                                           {"x_scale", i32},
-                                           {"x_isvalid", i1},
-                                           {"seed", i64},
-                                           {"seed_isvalid", i1},
-                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("isnull_decimal128", i1,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("isnotnull_decimal128", i1,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("isnumeric_decimal128", i1,
-                                                       {
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"x_isvalid", i1},
-                                                       }));
-
-  ARROW_RETURN_NOT_OK(
-      decimal_ir->BuildDecimalFunction("is_distinct_from_decimal128_decimal128", i1,
-                                       {
-                                           {"x_value", i128},
-                                           {"x_precision", i32},
-                                           {"x_scale", i32},
-                                           {"x_isvalid", i1},
-                                           {"y_value", i128},
-                                           {"y_precision", i32},
-                                           {"y_scale", i32},
-                                           {"y_isvalid", i1},
-                                       }));
-
-  ARROW_RETURN_NOT_OK(
-      decimal_ir->BuildDecimalFunction("is_not_distinct_from_decimal128_decimal128", i1,
-                                       {
-                                           {"x_value", i128},
-                                           {"x_precision", i32},
-                                           {"x_scale", i32},
-                                           {"x_isvalid", i1},
-                                           {"y_value", i128},
-                                           {"y_precision", i32},
-                                           {"y_scale", i32},
-                                           {"y_isvalid", i1},
-                                       }));
-
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castDECIMAL_utf8", i128,
-                                                       {
-                                                           {"context", i64},
-                                                           {"in", i8_ptr},
-                                                           {"in_len", i32},
-                                                           {"out_precision", i32},
-                                                           {"out_scale", i32},
-                                                       }));
-  ARROW_RETURN_NOT_OK(decimal_ir->BuildDecimalFunction("castVARCHAR_decimal128_int64",
-                                                       i8_ptr,
-                                                       {
-                                                           {"context", i64},
-                                                           {"x_value", i128},
-                                                           {"x_precision", i32},
-                                                           {"x_scale", i32},
-                                                           {"out_len_param", i64},
-                                                           {"out_length", i32_ptr},
-                                                       }));
-
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kEQFunction, llvm::ICmpInst::ICMP_EQ));
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kNEFunction, llvm::ICmpInst::ICMP_NE));
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kLTFunction, llvm::ICmpInst::ICMP_SLT));
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kLEFunction, llvm::ICmpInst::ICMP_SLE));
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kGTFunction, llvm::ICmpInst::ICMP_SGT));
+  ARROW_RETURN_NOT_OK(decimal_ir->BuildCompare(kGEFunction, llvm::ICmpInst::ICMP_SGE));
   return Status::OK();
 }
 
diff --git a/cpp/src/gandiva/decimal_ir.h b/cpp/src/gandiva/decimal_ir.h
index c2a22b3..6503c82 100644
--- a/cpp/src/gandiva/decimal_ir.h
+++ b/cpp/src/gandiva/decimal_ir.h
@@ -37,6 +37,10 @@ class DecimalIR : public FunctionIRBuilder {
 
   void EnableTraces() { enable_ir_traces_ = true; }
 
+  llvm::Value* CallDecimalFunction(const std::string& function_name,
+                                   llvm::Type* return_type,
+                                   const std::vector<llvm::Value*>& args);
+
  private:
   /// The intrinsic fn for divide with small divisors is about 10x slower, so not
   /// using these.
diff --git a/cpp/src/gandiva/function_registry_arithmetic.cc b/cpp/src/gandiva/function_registry_arithmetic.cc
index f7f88bb..f5d5ce7 100644
--- a/cpp/src/gandiva/function_registry_arithmetic.cc
+++ b/cpp/src/gandiva/function_registry_arithmetic.cc
@@ -46,7 +46,9 @@ 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),
diff --git a/cpp/src/gandiva/gdv_function_stubs.cc b/cpp/src/gandiva/gdv_function_stubs.cc
index 1d8fe9b..08d12d0 100644
--- a/cpp/src/gandiva/gdv_function_stubs.cc
+++ b/cpp/src/gandiva/gdv_function_stubs.cc
@@ -119,10 +119,10 @@ char* gdv_fn_dec_to_string(int64_t context, int64_t x_high, uint64_t x_low,
   std::string dec_str = dec.ToString(x_scale);
   *dec_str_len = static_cast<int32_t>(dec_str.length());
   char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *dec_str_len));
-  if (ret == NULLPTR) {
+  if (ret == nullptr) {
     std::string err_msg = "Could not allocate memory for string: " + dec_str;
     gdv_fn_context_set_error_msg(context, err_msg.data());
-    return NULLPTR;
+    return nullptr;
   }
   memcpy(ret, dec_str.data(), *dec_str_len);
   return ret;
diff --git a/cpp/src/gandiva/llvm_generator.cc b/cpp/src/gandiva/llvm_generator.cc
index f540755..57f67cb 100644
--- a/cpp/src/gandiva/llvm_generator.cc
+++ b/cpp/src/gandiva/llvm_generator.cc
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "gandiva/bitmap_accumulator.h"
+#include "gandiva/decimal_ir.h"
 #include "gandiva/dex.h"
 #include "gandiva/expr_decomposer.h"
 #include "gandiva/expression.h"
@@ -1112,6 +1113,7 @@ LValuePtr LLVMGenerator::Visitor::BuildFunctionCall(const NativeFunction* func,
   auto types = generator_->types();
   auto arrow_return_type_id = arrow_return_type->id();
   auto llvm_return_type = types->IRType(arrow_return_type_id);
+  DecimalIR decimalIR(generator_->engine_.get());
 
   if (arrow_return_type_id == arrow::Type::DECIMAL) {
     // For decimal fns, the output precision/scale are passed along as parameters.
@@ -1127,10 +1129,16 @@ LValuePtr LLVMGenerator::Visitor::BuildFunctionCall(const NativeFunction* func,
     params->push_back(ret_lvalue->scale());
 
     // Make the function call
-    auto out = generator_->AddFunctionCall(func->pc_name(), llvm_return_type, *params);
+    auto out = decimalIR.CallDecimalFunction(func->pc_name(), llvm_return_type, *params);
     ret_lvalue->set_data(out);
     return std::move(ret_lvalue);
   } else {
+    bool isDecimalFunction = false;
+    for (auto& arg : *params) {
+      if (arg->getType() == types->i128_type()) {
+        isDecimalFunction = true;
+      }
+    }
     // add extra arg for return length for variable len return types (alloced on stack).
     llvm::AllocaInst* result_len_ptr = nullptr;
     if (arrow::is_binary_like(arrow_return_type_id)) {
@@ -1142,7 +1150,10 @@ LValuePtr LLVMGenerator::Visitor::BuildFunctionCall(const NativeFunction* func,
 
     // Make the function call
     llvm::IRBuilder<>* builder = ir_builder();
-    auto value = generator_->AddFunctionCall(func->pc_name(), llvm_return_type, *params);
+    auto value =
+        isDecimalFunction
+            ? decimalIR.CallDecimalFunction(func->pc_name(), llvm_return_type, *params)
+            : generator_->AddFunctionCall(func->pc_name(), llvm_return_type, *params);
     auto value_len =
         (result_len_ptr == nullptr) ? nullptr : builder->CreateLoad(result_len_ptr);
     return std::make_shared<LValue>(value, value_len);
diff --git a/cpp/src/gandiva/precompiled/decimal_wrapper.cc b/cpp/src/gandiva/precompiled/decimal_wrapper.cc
index 620b443..66ccb3e 100644
--- a/cpp/src/gandiva/precompiled/decimal_wrapper.cc
+++ b/cpp/src/gandiva/precompiled/decimal_wrapper.cc
@@ -35,12 +35,11 @@ void add_large_decimal128_decimal128(int64_t x_high, uint64_t x_low, int32_t x_p
 }
 
 FORCE_INLINE
-void multiply_internal_decimal128_decimal128(int64_t x_high, uint64_t x_low,
-                                             int32_t x_precision, int32_t x_scale,
-                                             int64_t y_high, uint64_t y_low,
-                                             int32_t y_precision, int32_t y_scale,
-                                             int32_t out_precision, int32_t out_scale,
-                                             int64_t* out_high, uint64_t* out_low) {
+void multiply_decimal128_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                                    int32_t x_scale, int64_t y_high, uint64_t y_low,
+                                    int32_t y_precision, int32_t y_scale,
+                                    int32_t out_precision, int32_t out_scale,
+                                    int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x(x_high, x_low, x_precision, x_scale);
   gandiva::BasicDecimalScalar128 y(y_high, y_low, y_precision, y_scale);
   bool overflow;
@@ -53,10 +52,11 @@ void multiply_internal_decimal128_decimal128(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-void divide_internal_decimal128_decimal128(
-    int64_t context, int64_t x_high, uint64_t x_low, int32_t x_precision, int32_t x_scale,
-    int64_t y_high, uint64_t y_low, int32_t y_precision, int32_t y_scale,
-    int32_t out_precision, int32_t out_scale, int64_t* out_high, uint64_t* out_low) {
+void divide_decimal128_decimal128(int64_t context, int64_t x_high, uint64_t x_low,
+                                  int32_t x_precision, int32_t x_scale, int64_t y_high,
+                                  uint64_t y_low, int32_t y_precision, int32_t y_scale,
+                                  int32_t out_precision, int32_t out_scale,
+                                  int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x(x_high, x_low, x_precision, x_scale);
   gandiva::BasicDecimalScalar128 y(y_high, y_low, y_precision, y_scale);
   bool overflow;
@@ -69,12 +69,11 @@ void divide_internal_decimal128_decimal128(
 }
 
 FORCE_INLINE
-void mod_internal_decimal128_decimal128(int64_t context, int64_t x_high, uint64_t x_low,
-                                        int32_t x_precision, int32_t x_scale,
-                                        int64_t y_high, uint64_t y_low,
-                                        int32_t y_precision, int32_t y_scale,
-                                        int32_t out_precision, int32_t out_scale,
-                                        int64_t* out_high, uint64_t* out_low) {
+void mod_decimal128_decimal128(int64_t context, int64_t x_high, uint64_t x_low,
+                               int32_t x_precision, int32_t x_scale, int64_t y_high,
+                               uint64_t y_low, int32_t y_precision, int32_t y_scale,
+                               int32_t out_precision, int32_t out_scale,
+                               int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x(x_high, x_low, x_precision, x_scale);
   gandiva::BasicDecimalScalar128 y(y_high, y_low, y_precision, y_scale);
   bool overflow;
@@ -87,7 +86,7 @@ void mod_internal_decimal128_decimal128(int64_t context, int64_t x_high, uint64_
 }
 
 FORCE_INLINE
-int32_t compare_internal_decimal128_decimal128(int64_t x_high, uint64_t x_low,
+int32_t compare_decimal128_decimal128_internal(int64_t x_high, uint64_t x_low,
                                                int32_t x_precision, int32_t x_scale,
                                                int64_t y_high, uint64_t y_low,
                                                int32_t y_precision, int32_t y_scale) {
@@ -98,9 +97,9 @@ int32_t compare_internal_decimal128_decimal128(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-void abs_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                             int32_t x_scale, int32_t out_precision, int32_t out_scale,
-                             int64_t* out_high, uint64_t* out_low) {
+void abs_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision, int32_t x_scale,
+                    int32_t out_precision, int32_t out_scale, int64_t* out_high,
+                    uint64_t* out_low) {
   gandiva::BasicDecimal128 x(x_high, x_low);
   x.Abs();
   *out_high = x.high_bits();
@@ -108,9 +107,9 @@ void abs_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision
 }
 
 FORCE_INLINE
-void ceil_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                              int32_t x_scale, int32_t out_precision, int32_t out_scale,
-                              int64_t* out_high, uint64_t* out_low) {
+void ceil_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision, int32_t x_scale,
+                     int32_t out_precision, int32_t out_scale, int64_t* out_high,
+                     uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -120,9 +119,9 @@ void ceil_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precisio
 }
 
 FORCE_INLINE
-void floor_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                               int32_t x_scale, int32_t out_precision, int32_t out_scale,
-                               int64_t* out_high, uint64_t* out_low) {
+void floor_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                      int32_t x_scale, int32_t out_precision, int32_t out_scale,
+                      int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -132,9 +131,9 @@ void floor_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precisi
 }
 
 FORCE_INLINE
-void round_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                               int32_t x_scale, int32_t out_precision, int32_t out_scale,
-                               int64_t* out_high, uint64_t* out_low) {
+void round_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                      int32_t x_scale, int32_t out_precision, int32_t out_scale,
+                      int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -144,10 +143,10 @@ void round_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precisi
 }
 
 FORCE_INLINE
-void round_decimal128_int32_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                     int32_t x_scale, int32_t rounding_scale,
-                                     int32_t out_precision, int32_t out_scale,
-                                     int64_t* out_high, uint64_t* out_low) {
+void round_decimal128_int32(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                            int32_t x_scale, int32_t rounding_scale,
+                            int32_t out_precision, int32_t out_scale, int64_t* out_high,
+                            uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -157,10 +156,9 @@ void round_decimal128_int32_internal(int64_t x_high, uint64_t x_low, int32_t x_p
 }
 
 FORCE_INLINE
-void truncate_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                  int32_t x_scale, int32_t out_precision,
-                                  int32_t out_scale, int64_t* out_high,
-                                  uint64_t* out_low) {
+void truncate_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                         int32_t x_scale, int32_t out_precision, int32_t out_scale,
+                         int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -170,11 +168,10 @@ void truncate_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_prec
 }
 
 FORCE_INLINE
-void truncate_decimal128_int32_internal(int64_t x_high, uint64_t x_low,
-                                        int32_t x_precision, int32_t x_scale,
-                                        int32_t rounding_scale, int32_t out_precision,
-                                        int32_t out_scale, int64_t* out_high,
-                                        uint64_t* out_low) {
+void truncate_decimal128_int32(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                               int32_t x_scale, int32_t rounding_scale,
+                               int32_t out_precision, int32_t out_scale,
+                               int64_t* out_high, uint64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -184,8 +181,8 @@ void truncate_decimal128_int32_internal(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-double castFLOAT8_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                      int32_t x_scale) {
+double castFLOAT8_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                             int32_t x_scale) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -193,8 +190,8 @@ double castFLOAT8_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_
 }
 
 FORCE_INLINE
-int64_t castBIGINT_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                       int32_t x_precision, int32_t x_scale) {
+int64_t castBIGINT_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                              int32_t x_scale) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
 
   bool overflow = false;
@@ -202,8 +199,8 @@ int64_t castBIGINT_decimal128_internal(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-void castDECIMAL_int64_internal(int64_t in, int32_t x_precision, int32_t x_scale,
-                                int64_t* out_high, uint64_t* out_low) {
+void castDECIMAL_int64(int64_t in, int32_t x_precision, int32_t x_scale,
+                       int64_t* out_high, uint64_t* out_low) {
   bool overflow = false;
   auto out = gandiva::decimalops::FromInt64(in, x_precision, x_scale, &overflow);
   *out_high = out.high_bits();
@@ -211,8 +208,14 @@ void castDECIMAL_int64_internal(int64_t in, int32_t x_precision, int32_t x_scale
 }
 
 FORCE_INLINE
-void castDECIMAL_float64_internal(double in, int32_t x_precision, int32_t x_scale,
-                                  int64_t* out_high, uint64_t* out_low) {
+void castDECIMAL_int32(int32_t in, int32_t x_precision, int32_t x_scale,
+                       int64_t* out_high, uint64_t* out_low) {
+  castDECIMAL_int64(in, x_precision, x_scale, out_high, out_low);
+}
+
+FORCE_INLINE
+void castDECIMAL_float64(double in, int32_t x_precision, int32_t x_scale,
+                         int64_t* out_high, uint64_t* out_low) {
   bool overflow = false;
   auto out = gandiva::decimalops::FromDouble(in, x_precision, x_scale, &overflow);
   *out_high = out.high_bits();
@@ -220,10 +223,15 @@ void castDECIMAL_float64_internal(double in, int32_t x_precision, int32_t x_scal
 }
 
 FORCE_INLINE
-void castDECIMAL_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                     int32_t x_scale, int32_t out_precision,
-                                     int32_t out_scale, int64_t* out_high,
-                                     int64_t* out_low) {
+void castDECIMAL_float32(float in, int32_t x_precision, int32_t x_scale,
+                         int64_t* out_high, uint64_t* out_low) {
+  castDECIMAL_float64(in, x_precision, x_scale, out_high, out_low);
+}
+
+FORCE_INLINE
+void castDECIMAL_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                            int32_t x_scale, int32_t out_precision, int32_t out_scale,
+                            int64_t* out_high, int64_t* out_low) {
   gandiva::BasicDecimalScalar128 x({x_high, x_low}, x_precision, x_scale);
   bool overflow = false;
   auto out = gandiva::decimalops::Convert(x, out_precision, out_scale, &overflow);
@@ -232,32 +240,31 @@ void castDECIMAL_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_p
 }
 
 FORCE_INLINE
-int32_t hash32_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                   int32_t x_scale, boolean x_isvalid) {
+int32_t hash32_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                          int32_t x_scale, boolean x_isvalid) {
   return x_isvalid
              ? hash32_buf(gandiva::BasicDecimal128(x_high, x_low).ToBytes().data(), 16, 0)
              : 0;
 }
 
 FORCE_INLINE
-int32_t hash_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                 int32_t x_scale, boolean x_isvalid) {
-  return hash32_decimal128_internal(x_high, x_low, x_precision, x_scale, x_isvalid);
+int32_t hash_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                        int32_t x_scale, boolean x_isvalid) {
+  return hash32_decimal128(x_high, x_low, x_precision, x_scale, x_isvalid);
 }
 
 FORCE_INLINE
-int64_t hash64_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                   int32_t x_scale, boolean x_isvalid) {
+int64_t hash64_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                          int32_t x_scale, boolean x_isvalid) {
   return x_isvalid
              ? hash64_buf(gandiva::BasicDecimal128(x_high, x_low).ToBytes().data(), 16, 0)
              : 0;
 }
 
 FORCE_INLINE
-int32_t hash32WithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                           int32_t x_precision, int32_t x_scale,
-                                           boolean x_isvalid, int32_t seed,
-                                           boolean seed_isvalid) {
+int32_t hash32WithSeed_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                                  int32_t x_scale, boolean x_isvalid, int32_t seed,
+                                  boolean seed_isvalid) {
   if (!x_isvalid) {
     return seed;
   }
@@ -265,10 +272,9 @@ int32_t hash32WithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-int64_t hash64WithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                           int32_t x_precision, int32_t x_scale,
-                                           boolean x_isvalid, int64_t seed,
-                                           boolean seed_isvalid) {
+int64_t hash64WithSeed_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                                  int32_t x_scale, boolean x_isvalid, int64_t seed,
+                                  boolean seed_isvalid) {
   if (!x_isvalid) {
     return seed;
   }
@@ -276,28 +282,26 @@ int64_t hash64WithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
 }
 
 FORCE_INLINE
-int32_t hash32AsDouble_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                           int32_t x_precision, int32_t x_scale,
-                                           boolean x_isvalid) {
+int32_t hash32AsDouble_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                                  int32_t x_scale, boolean x_isvalid) {
   return x_isvalid
              ? hash32_buf(gandiva::BasicDecimal128(x_high, x_low).ToBytes().data(), 16, 0)
              : 0;
 }
 
 FORCE_INLINE
-int64_t hash64AsDouble_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                           int32_t x_precision, int32_t x_scale,
-                                           boolean x_isvalid) {
+int64_t hash64AsDouble_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                                  int32_t x_scale, boolean x_isvalid) {
   return x_isvalid
              ? hash64_buf(gandiva::BasicDecimal128(x_high, x_low).ToBytes().data(), 16, 0)
              : 0;
 }
 
 FORCE_INLINE
-int32_t hash32AsDoubleWithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                                   int32_t x_precision, int32_t x_scale,
-                                                   boolean x_isvalid, int32_t seed,
-                                                   boolean seed_isvalid) {
+int32_t hash32AsDoubleWithSeed_decimal128(int64_t x_high, uint64_t x_low,
+                                          int32_t x_precision, int32_t x_scale,
+                                          boolean x_isvalid, int32_t seed,
+                                          boolean seed_isvalid) {
   if (!x_isvalid) {
     return seed;
   }
@@ -305,10 +309,10 @@ int32_t hash32AsDoubleWithSeed_decimal128_internal(int64_t x_high, uint64_t x_lo
 }
 
 FORCE_INLINE
-int64_t hash64AsDoubleWithSeed_decimal128_internal(int64_t x_high, uint64_t x_low,
-                                                   int32_t x_precision, int32_t x_scale,
-                                                   boolean x_isvalid, int64_t seed,
-                                                   boolean seed_isvalid) {
+int64_t hash64AsDoubleWithSeed_decimal128(int64_t x_high, uint64_t x_low,
+                                          int32_t x_precision, int32_t x_scale,
+                                          boolean x_isvalid, int64_t seed,
+                                          boolean seed_isvalid) {
   if (!x_isvalid) {
     return seed;
   }
@@ -316,52 +320,54 @@ int64_t hash64AsDoubleWithSeed_decimal128_internal(int64_t x_high, uint64_t x_lo
 }
 
 FORCE_INLINE
-boolean isnull_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                   int32_t x_scale, boolean x_isvalid) {
+boolean isnull_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                          int32_t x_scale, boolean x_isvalid) {
   return !x_isvalid;
 }
 
 FORCE_INLINE
-boolean isnotnull_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                      int32_t x_scale, boolean x_isvalid) {
+boolean isnotnull_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                             int32_t x_scale, boolean x_isvalid) {
   return x_isvalid;
 }
 
 FORCE_INLINE
-boolean isnumeric_decimal128_internal(int64_t x_high, uint64_t x_low, int32_t x_precision,
-                                      int32_t x_scale, boolean x_isvalid) {
+boolean isnumeric_decimal128(int64_t x_high, uint64_t x_low, int32_t x_precision,
+                             int32_t x_scale, boolean x_isvalid) {
   return x_isvalid;
 }
 
 FORCE_INLINE
-boolean is_not_distinct_from_decimal128_decimal128_internal(
-    int64_t x_high, uint64_t x_low, int32_t x_precision, int32_t x_scale,
-    boolean x_isvalid, int64_t y_high, uint64_t y_low, int32_t y_precision,
-    int32_t y_scale, boolean y_isvalid) {
+boolean is_not_distinct_from_decimal128_decimal128(int64_t x_high, uint64_t x_low,
+                                                   int32_t x_precision, int32_t x_scale,
+                                                   boolean x_isvalid, int64_t y_high,
+                                                   uint64_t y_low, int32_t y_precision,
+                                                   int32_t y_scale, boolean y_isvalid) {
   if (x_isvalid != y_isvalid) {
     return false;
   }
   if (!x_isvalid) {
     return true;
   }
-  return 0 == compare_internal_decimal128_decimal128(x_high, x_low, x_precision, x_scale,
+  return 0 == compare_decimal128_decimal128_internal(x_high, x_low, x_precision, x_scale,
                                                      y_high, y_low, y_precision, y_scale);
 }
 
 FORCE_INLINE
-boolean is_distinct_from_decimal128_decimal128_internal(
-    int64_t x_high, uint64_t x_low, int32_t x_precision, int32_t x_scale,
-    boolean x_isvalid, int64_t y_high, uint64_t y_low, int32_t y_precision,
-    int32_t y_scale, boolean y_isvalid) {
-  return !is_not_distinct_from_decimal128_decimal128_internal(
-      x_high, x_low, x_precision, x_scale, x_isvalid, y_high, y_low, y_precision, y_scale,
-      y_isvalid);
+boolean is_distinct_from_decimal128_decimal128(int64_t x_high, uint64_t x_low,
+                                               int32_t x_precision, int32_t x_scale,
+                                               boolean x_isvalid, int64_t y_high,
+                                               uint64_t y_low, int32_t y_precision,
+                                               int32_t y_scale, boolean y_isvalid) {
+  return !is_not_distinct_from_decimal128_decimal128(x_high, x_low, x_precision, x_scale,
+                                                     x_isvalid, y_high, y_low,
+                                                     y_precision, y_scale, y_isvalid);
 }
 
 FORCE_INLINE
-void castDECIMAL_utf8_internal(int64_t context, const char* in, int32_t in_length,
-                               int32_t out_precision, int32_t out_scale,
-                               int64_t* out_high, uint64_t* out_low) {
+void castDECIMAL_utf8(int64_t context, const char* in, int32_t in_length,
+                      int32_t out_precision, int32_t out_scale, int64_t* out_high,
+                      uint64_t* out_low) {
   int64_t dec_high_from_str;
   uint64_t dec_low_from_str;
   int32_t precision_from_str;
@@ -382,10 +388,9 @@ void castDECIMAL_utf8_internal(int64_t context, const char* in, int32_t in_lengt
 }
 
 FORCE_INLINE
-char* castVARCHAR_decimal128_int64_internal(int64_t context, int64_t x_high,
-                                            uint64_t x_low, int32_t x_precision,
-                                            int32_t x_scale, int64_t out_len_param,
-                                            int32_t* out_length) {
+char* castVARCHAR_decimal128_int64(int64_t context, int64_t x_high, uint64_t x_low,
+                                   int32_t x_precision, int32_t x_scale,
+                                   int64_t out_len_param, int32_t* out_length) {
   int32_t full_dec_str_len;
   char* dec_str =
       gdv_fn_dec_to_string(context, x_high, x_low, x_scale, &full_dec_str_len);
diff --git a/cpp/src/gandiva/tests/decimal_test.cc b/cpp/src/gandiva/tests/decimal_test.cc
index 1762d5b..2c29ccf 100644
--- a/cpp/src/gandiva/tests/decimal_test.cc
+++ b/cpp/src/gandiva/tests/decimal_test.cc
@@ -412,15 +412,22 @@ TEST_F(TestDecimal, TestCastFunctions) {
   constexpr int32_t scale = 2;
   auto decimal_type = std::make_shared<arrow::Decimal128Type>(precision, scale);
   auto decimal_type_scale_1 = std::make_shared<arrow::Decimal128Type>(precision, 1);
-  auto field_int64 = field("intt64", arrow::int64());
+  auto field_int32 = field("int32", arrow::int32());
+  auto field_int64 = field("int64", arrow::int64());
+  auto field_float32 = field("float32", arrow::float32());
   auto field_float64 = field("float64", arrow::float64());
   auto field_dec = field("dec", decimal_type);
-  auto schema = arrow::schema({field_int64, field_float64, field_dec});
+  auto schema =
+      arrow::schema({field_int32, field_int64, field_float32, field_float64, field_dec});
 
   // build expressions
   auto exprs = std::vector<ExpressionPtr>{
+      TreeExprBuilder::MakeExpression("castDECIMAL", {field_int32},
+                                      field("int32_to_dec", decimal_type)),
       TreeExprBuilder::MakeExpression("castDECIMAL", {field_int64},
                                       field("int64_to_dec", decimal_type)),
+      TreeExprBuilder::MakeExpression("castDECIMAL", {field_float32},
+                                      field("float32_to_dec", decimal_type)),
       TreeExprBuilder::MakeExpression("castDECIMAL", {field_float64},
                                       field("float64_to_dec", decimal_type)),
       TreeExprBuilder::MakeExpression("castDECIMAL", {field_dec},
@@ -440,15 +447,18 @@ TEST_F(TestDecimal, TestCastFunctions) {
   int num_records = 4;
   auto validity = {true, true, true, true};
 
+  auto array_int32 = MakeArrowArrayInt32({123, 158, -123, -158});
   auto array_int64 = MakeArrowArrayInt64({123, 158, -123, -158});
+  auto array_float32 = MakeArrowArrayFloat32({1.23f, 1.58f, -1.23f, -1.58f});
   auto array_float64 = MakeArrowArrayFloat64({1.23, 1.58, -1.23, -1.58});
   auto array_dec = MakeArrowArrayDecimal(
       decimal_type, MakeDecimalVector({"1.23", "1.58", "-1.23", "-1.58"}, scale),
       validity);
 
   // prepare input record batch
-  auto in_batch = arrow::RecordBatch::Make(schema, num_records,
-                                           {array_int64, array_float64, array_dec});
+  auto in_batch = arrow::RecordBatch::Make(
+      schema, num_records,
+      {array_int32, array_int64, array_float32, array_float64, array_dec});
 
   // Evaluate expression
   arrow::ArrayVector outputs;
@@ -457,28 +467,34 @@ TEST_F(TestDecimal, TestCastFunctions) {
 
   // Validate results
 
-  // castDECIMAL(int64)
+  // castDECIMAL(int32)
   EXPECT_ARROW_ARRAY_EQUALS(
       MakeArrowArrayDecimal(decimal_type,
                             MakeDecimalVector({"123", "158", "-123", "-158"}, scale),
                             validity),
       outputs[0]);
 
+  // castDECIMAL(int64)
+  EXPECT_ARROW_ARRAY_EQUALS(array_dec, outputs[2]);
+
+  // castDECIMAL(float32)
+  EXPECT_ARROW_ARRAY_EQUALS(array_dec, outputs[2]);
+
   // castDECIMAL(float64)
-  EXPECT_ARROW_ARRAY_EQUALS(array_dec, outputs[1]);
+  EXPECT_ARROW_ARRAY_EQUALS(array_dec, outputs[3]);
 
   // castDECIMAL(decimal)
   EXPECT_ARROW_ARRAY_EQUALS(
       MakeArrowArrayDecimal(arrow::decimal(precision, 1),
                             MakeDecimalVector({"1.2", "1.6", "-1.2", "-1.6"}, 1),
                             validity),
-      outputs[2]);
+      outputs[4]);
 
   // castBIGINT(decimal)
-  EXPECT_ARROW_ARRAY_EQUALS(MakeArrowArrayInt64({1, 1, -1, -1}), outputs[3]);
+  EXPECT_ARROW_ARRAY_EQUALS(MakeArrowArrayInt64({1, 1, -1, -1}), outputs[5]);
 
   // castDOUBLE(decimal)
-  EXPECT_ARROW_ARRAY_EQUALS(array_float64, outputs[4]);
+  EXPECT_ARROW_ARRAY_EQUALS(array_float64, outputs[6]);
 }
 
 // isnull, isnumeric