Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 1 addition & 17 deletions cpp/src/gandiva/gdv_function_stubs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1364,8 +1364,7 @@ arrow::Status ExportedStubFunctions::AddMappings(Engine* engine) const {
};

engine->AddGlobalMappingForFunc(
"gdv_fn_cast_intervalday_utf8_int32",
types->i64_type() /*return_type*/, args,
"gdv_fn_cast_intervalday_utf8_int32", types->i64_type() /*return_type*/, args,
reinterpret_cast<void*>(gdv_fn_cast_intervalday_utf8_int32));

// gdv_fn_cast_intervalyear_utf8
Expand All @@ -1382,21 +1381,6 @@ arrow::Status ExportedStubFunctions::AddMappings(Engine* engine) const {
types->i32_type() /*return_type*/, args,
reinterpret_cast<void*>(gdv_fn_cast_intervalyear_utf8));

#define ADD_MAPPING_FOR_NUMERIC_LIST_TYPE_POPULATE_FUNCTION( \
LLVM_TYPE, DATA_TYPE) \
args = {types->i64_type(), types->i8_ptr_type(), types->i32_ptr_type(), \
types->i64_type(), types->LLVM_TYPE##_ptr_type(), \
types->i32_type(), types->i32_ptr_type()}; \
engine->AddGlobalMappingForFunc( \
"gdv_fn_populate_list_" #DATA_TYPE "_vector", \
types->i32_type() /*return_type*/, args, \
reinterpret_cast<void*>(gdv_fn_populate_list_##DATA_TYPE##_vector));

ADD_MAPPING_FOR_NUMERIC_LIST_TYPE_POPULATE_FUNCTION(i32, int32_t)
ADD_MAPPING_FOR_NUMERIC_LIST_TYPE_POPULATE_FUNCTION(i64, int64_t)
ADD_MAPPING_FOR_NUMERIC_LIST_TYPE_POPULATE_FUNCTION(float, float)
ADD_MAPPING_FOR_NUMERIC_LIST_TYPE_POPULATE_FUNCTION(double, double)

// gdv_fn_cast_intervalyear_utf8_int32
args = {
types->i64_type(), // context
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/gandiva/precompiled/decimal_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ void castDECIMAL_utf8(int64_t context, const char* in, int32_t in_length,
gdv_fn_dec_from_string(context, in, in_length, &precision_from_str, &scale_from_str,
&dec_high_from_str, &dec_low_from_str);
if (status != 0) {
*out_high = 0;
*out_low = 0;
return;
}

Expand Down
41 changes: 41 additions & 0 deletions cpp/src/gandiva/tests/decimal_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <sstream>

#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include "arrow/memory_pool.h"
#include "arrow/status.h"
Expand Down Expand Up @@ -1236,4 +1237,44 @@ TEST_F(TestDecimal, TestSha) {
EXPECT_NE(value_at_position, response->GetScalar(i - 1).ValueOrDie()->ToString());
}
}

TEST_F(TestDecimal, TestCastDecimalVarCharInvalidInputInvalidOutput) {
auto decimal_type_10_0 = std::make_shared<arrow::Decimal128Type>(10, 0);
auto decimal_type_38_30 = std::make_shared<arrow::Decimal128Type>(38, 30);
auto decimal_type_38_27 = std::make_shared<arrow::Decimal128Type>(38, 27);

auto field_str = field("in_str", utf8());
auto schema = arrow::schema({field_str});
auto res_bool = field("res_bool", arrow::boolean());

// This is minimal possible expression to reproduce SIGSEGV
// equal(multiply(castDecimal(10), castDecimal(100)), castDECIMAL("foo"))
auto int_literal = TreeExprBuilder::MakeLiteral(static_cast<int32_t>(100));
auto int_literal_multiply = TreeExprBuilder::MakeLiteral(static_cast<int32_t>(10));
auto string_literal = TreeExprBuilder::MakeStringLiteral("foo");
auto cast_multiply_literal = TreeExprBuilder::MakeFunction(
"castDECIMAL", {int_literal_multiply}, decimal_type_10_0);
auto cast_int_literal =
TreeExprBuilder::MakeFunction("castDECIMAL", {int_literal}, decimal_type_38_30);
auto cast_string_func =
TreeExprBuilder::MakeFunction("castDECIMAL", {string_literal}, decimal_type_38_30);
auto multiply_func = TreeExprBuilder::MakeFunction(
"multiply", {cast_multiply_literal, cast_int_literal}, decimal_type_38_27);
auto equal_func = TreeExprBuilder::MakeFunction(
"equal", {multiply_func, cast_string_func}, arrow::boolean());
auto expr = TreeExprBuilder::MakeExpression(equal_func, res_bool);

std::shared_ptr<Projector> projector;

ASSERT_OK(Projector::Make(schema, {expr}, TestConfiguration(), &projector));

int num_records = 1;
auto invalid_in = MakeArrowArrayUtf8({"1.345"}, {true});
auto in_batch = arrow::RecordBatch::Make(schema, num_records, {invalid_in});

arrow::ArrayVector outputs;
auto status = projector->Evaluate(*in_batch, pool_, &outputs);
ASSERT_NOT_OK(status);
ASSERT_THAT(status.message(), ::testing::HasSubstr("not a valid decimal128 number"));
}
} // namespace gandiva
Loading