Skip to content

Commit 9fc9ea0

Browse files
committed
GH-46708: [C++][Gandiva] Added zero return values for castDECIMAL_utf8 if in value can not be parsed
1 parent 832bfa1 commit 9fc9ea0

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

cpp/src/gandiva/precompiled/decimal_wrapper.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ void castDECIMAL_utf8(int64_t context, const char* in, int32_t in_length,
406406
gdv_fn_dec_from_string(context, in, in_length, &precision_from_str, &scale_from_str,
407407
&dec_high_from_str, &dec_low_from_str);
408408
if (status != 0) {
409+
*out_high = 0;
410+
*out_low = 0;
409411
return;
410412
}
411413

cpp/src/gandiva/tests/decimal_test.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,4 +1237,42 @@ TEST_F(TestDecimal, TestSha) {
12371237
EXPECT_NE(value_at_position, response->GetScalar(i - 1).ValueOrDie()->ToString());
12381238
}
12391239
}
1240+
1241+
TEST_F(TestDecimal, TestCastDecimalVarCharInvalidInputInvalidOutput) {
1242+
auto decimal_type_10_0 = std::make_shared<arrow::Decimal128Type>(10, 0);
1243+
auto decimal_type_38_30 = std::make_shared<arrow::Decimal128Type>(38, 30);
1244+
auto decimal_type_38_27 = std::make_shared<arrow::Decimal128Type>(38, 27);
1245+
1246+
auto field_str = field("in_str", utf8());
1247+
auto schema = arrow::schema({field_str});
1248+
auto res_bool = field("res_bool", arrow::boolean());
1249+
1250+
auto int_literal = TreeExprBuilder::MakeLiteral((int32_t)100);
1251+
auto negative_literal = TreeExprBuilder::MakeLiteral((int32_t)-1);
1252+
auto string_literal = TreeExprBuilder::MakeStringLiteral("foo");
1253+
auto cast_negative_literal =
1254+
TreeExprBuilder::MakeFunction("castDECIMAL", {negative_literal}, decimal_type_10_0);
1255+
auto cast_int_literal =
1256+
TreeExprBuilder::MakeFunction("castDECIMAL", {int_literal}, decimal_type_38_30);
1257+
auto cast_string_func =
1258+
TreeExprBuilder::MakeFunction("castDECIMAL", {string_literal}, decimal_type_38_30);
1259+
auto multiply_func =
1260+
TreeExprBuilder::MakeFunction("multiply", {cast_negative_literal, cast_int_literal}, decimal_type_38_27);
1261+
auto equal_func = TreeExprBuilder::MakeFunction("equal", {multiply_func, cast_string_func}, arrow::boolean());
1262+
auto expr = TreeExprBuilder::MakeExpression(equal_func, res_bool);
1263+
1264+
std::shared_ptr<Projector> projector;
1265+
1266+
auto status = Projector::Make(schema, {expr}, TestConfiguration(), &projector);
1267+
EXPECT_TRUE(status.ok()) << status.message();
1268+
1269+
int num_records = 1;
1270+
auto invalid_in = MakeArrowArrayUtf8({"1.345"}, {true});
1271+
auto in_batch_1 = arrow::RecordBatch::Make(schema, num_records, {invalid_in});
1272+
1273+
arrow::ArrayVector outputs_1;
1274+
status = projector->Evaluate(*in_batch_1, pool_, &outputs_1);
1275+
EXPECT_FALSE(status.ok()) << status.message();
1276+
EXPECT_NE(status.message().find("not a valid decimal128 number"), std::string::npos);
1277+
}
12401278
} // namespace gandiva

0 commit comments

Comments
 (0)