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/15 10:48:04 UTC
[arrow] branch master updated: ARROW-5925: [Gandiva][C++] fix
rounding in decimal to int cast
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 b3693db ARROW-5925: [Gandiva][C++] fix rounding in decimal to int cast
b3693db is described below
commit b3693db4590a60f5d33a098d1f57a5bfbc0c1f47
Author: Pindikura Ravindra <ra...@dremio.com>
AuthorDate: Mon Jul 15 16:17:41 2019 +0530
ARROW-5925: [Gandiva][C++] fix rounding in decimal to int cast
Author: Pindikura Ravindra <ra...@dremio.com>
Closes #4864 from pravindra/arrow-5925 and squashes the following commits:
2c432c36c <Pindikura Ravindra> ARROW-5925: fix rounding in decimal to int cast
---
cpp/src/gandiva/precompiled/decimal_ops.cc | 21 ++++++++++-----------
cpp/src/gandiva/precompiled/decimal_ops_test.cc | 4 ++--
cpp/src/gandiva/tests/decimal_test.cc | 2 +-
.../gandiva/evaluator/ProjectorDecimalTest.java | 6 +++---
4 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/cpp/src/gandiva/precompiled/decimal_ops.cc b/cpp/src/gandiva/precompiled/decimal_ops.cc
index 6f20f59..3dd74d7 100644
--- a/cpp/src/gandiva/precompiled/decimal_ops.cc
+++ b/cpp/src/gandiva/precompiled/decimal_ops.cc
@@ -467,7 +467,7 @@ int32_t Compare(const BasicDecimalScalar128& x, const BasicDecimalScalar128& y)
#define DECIMAL_OVERFLOW_IF(condition, overflow) \
do { \
- if (condition) { \
+ if (*overflow || (condition)) { \
*overflow = true; \
return 0; \
} \
@@ -531,16 +531,6 @@ BasicDecimal128 FromInt64(int64_t in, int32_t precision, int32_t scale, bool* ov
return in * BasicDecimal128::GetScaleMultiplier(scale);
}
-int64_t ToInt64(const BasicDecimalScalar128& in, bool* overflow) {
- BasicDecimal128 whole, fraction;
-
- in.value().GetWholeAndFraction(in.scale(), &whole, &fraction);
- DECIMAL_OVERFLOW_IF((whole > std::numeric_limits<int64_t>::max()) ||
- (whole < std::numeric_limits<int64_t>::min()),
- overflow);
- return static_cast<int64_t>(whole.low_bits());
-}
-
// Helper function to modify the scale and/or precision of a decimal value.
static BasicDecimal128 ModifyScaleAndPrecision(const BasicDecimalScalar128& x,
int32_t out_precision, int32_t out_scale,
@@ -702,5 +692,14 @@ BasicDecimal128 Convert(const BasicDecimalScalar128& x, int32_t out_precision,
RoundType::kRoundTypeHalfRoundUp, overflow);
}
+int64_t ToInt64(const BasicDecimalScalar128& in, bool* overflow) {
+ auto rounded = RoundWithPositiveScale(in, in.precision(), 0 /*scale*/,
+ RoundType::kRoundTypeHalfRoundUp, overflow);
+ DECIMAL_OVERFLOW_IF((rounded > std::numeric_limits<int64_t>::max()) ||
+ (rounded < std::numeric_limits<int64_t>::min()),
+ overflow);
+ return static_cast<int64_t>(rounded.low_bits());
+}
+
} // namespace decimalops
} // namespace gandiva
diff --git a/cpp/src/gandiva/precompiled/decimal_ops_test.cc b/cpp/src/gandiva/precompiled/decimal_ops_test.cc
index b4fe2e6..ef40e61 100644
--- a/cpp/src/gandiva/precompiled/decimal_ops_test.cc
+++ b/cpp/src/gandiva/precompiled/decimal_ops_test.cc
@@ -1009,8 +1009,8 @@ TEST_F(TestDecimalSql, ToInt64) {
std::vector<std::tuple<int64_t, DecimalScalar128, bool>> test_values = {
// simple ones
std::make_tuple(-16, DecimalScalar128{-16285, 38, 3}, false),
- std::make_tuple(-162, DecimalScalar128{-16285, 38, 2}, false),
- std::make_tuple(-1, DecimalScalar128{-16285, 38, 4}, false),
+ std::make_tuple(-163, DecimalScalar128{-16285, 38, 2}, false),
+ std::make_tuple(-2, DecimalScalar128{-16285, 38, 4}, false),
// border cases
std::make_tuple(INT64_MIN, DecimalScalar128{INT64_MIN, 38, 0}, false),
diff --git a/cpp/src/gandiva/tests/decimal_test.cc b/cpp/src/gandiva/tests/decimal_test.cc
index 2c29ccf..7e07c12 100644
--- a/cpp/src/gandiva/tests/decimal_test.cc
+++ b/cpp/src/gandiva/tests/decimal_test.cc
@@ -491,7 +491,7 @@ TEST_F(TestDecimal, TestCastFunctions) {
outputs[4]);
// castBIGINT(decimal)
- EXPECT_ARROW_ARRAY_EQUALS(MakeArrowArrayInt64({1, 1, -1, -1}), outputs[5]);
+ EXPECT_ARROW_ARRAY_EQUALS(MakeArrowArrayInt64({1, 2, -1, -2}), outputs[5]);
// castDOUBLE(decimal)
EXPECT_ARROW_ARRAY_EQUALS(array_float64, outputs[6]);
diff --git a/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ProjectorDecimalTest.java b/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ProjectorDecimalTest.java
index 8b38edb..37cc49b 100644
--- a/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ProjectorDecimalTest.java
+++ b/java/gandiva/src/test/java/org/apache/arrow/gandiva/evaluator/ProjectorDecimalTest.java
@@ -533,8 +533,8 @@ public class ProjectorDecimalTest extends org.apache.arrow.gandiva.evaluator.Bas
List<ValueVector> output = null;
ArrowRecordBatch batch = null;
try {
- int numRows = 4;
- String[] aValues = new String[]{"1.23", "1.58", "-1.23", "-1.58"};
+ int numRows = 5;
+ String[] aValues = new String[]{"1.23", "1.50", "98765.78", "-1.23", "-1.58"};
DecimalVector valuesa = decimalVector(aValues, decimalType.getPrecision(), decimalType.getScale());
batch = new ArrowRecordBatch(
numRows,
@@ -556,7 +556,7 @@ public class ProjectorDecimalTest extends org.apache.arrow.gandiva.evaluator.Bas
eval.evaluate(batch, output);
// compare the outputs.
- long[] expected = {1, 1, -1, -1};
+ long[] expected = {1, 2, 98766, -1, -2};
for (int i = 0; i < numRows; i++) {
assertFalse(resultVector.isNull(i));
assertEquals(expected[i], resultVector.get(i));