You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ee...@apache.org on 2022/07/28 22:00:40 UTC
[arrow] branch master updated: ARROW-17223: [C#] DecimalArray incorrectly appends values greater than Decimal.MaxValue / 2 and less than Decimal.MinValue / 2 (#13732)
This is an automated email from the ASF dual-hosted git repository.
eerhardt 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 f645ffa2a0 ARROW-17223: [C#] DecimalArray incorrectly appends values greater than Decimal.MaxValue / 2 and less than Decimal.MinValue / 2 (#13732)
f645ffa2a0 is described below
commit f645ffa2a089805ed6a4d2d64fd50ef40d7ddbc7
Author: Aleksei Smirnov <tl...@inbox.ru>
AuthorDate: Fri Jul 29 01:00:31 2022 +0300
ARROW-17223: [C#] DecimalArray incorrectly appends values greater than Decimal.MaxValue / 2 and less than Decimal.MinValue / 2 (#13732)
Authored-by: asmirnov82 <tl...@inbox.ru>
Signed-off-by: Eric Erhardt <er...@microsoft.com>
---
csharp/src/Apache.Arrow/DecimalUtility.cs | 42 +++++++++++-----------
.../Apache.Arrow.Tests/Decimal128ArrayTests.cs | 20 +++++++++++
.../Apache.Arrow.Tests/Decimal256ArrayTests.cs | 20 +++++++++++
3 files changed, 61 insertions(+), 21 deletions(-)
diff --git a/csharp/src/Apache.Arrow/DecimalUtility.cs b/csharp/src/Apache.Arrow/DecimalUtility.cs
index b7ee6b9a87..c117c26361 100644
--- a/csharp/src/Apache.Arrow/DecimalUtility.cs
+++ b/csharp/src/Apache.Arrow/DecimalUtility.cs
@@ -83,33 +83,33 @@ namespace Apache.Arrow
int[] decimalBits = decimal.GetBits(value);
int decScale = (decimalBits[3] >> 16) & 0x7F;
#if NETCOREAPP
- Span<byte> bigIntBytes = stackalloc byte[12];
+ Span<byte> bigIntBytes = stackalloc byte[13];
- for (int i = 0; i < 3; i++)
+ Span<byte> intBytes = stackalloc byte[4];
+ for (int i = 0; i < 3; i++)
+ {
+ int bit = decimalBits[i];
+ if (!BitConverter.TryWriteBytes(intBytes, bit))
+ throw new OverflowException($"Could not extract bytes from int {bit}");
+
+ for (int j = 0; j < 4; j++)
{
- int bit = decimalBits[i];
- Span<byte> intBytes = stackalloc byte[4];
- if (!BitConverter.TryWriteBytes(intBytes, bit))
- throw new OverflowException($"Could not extract bytes from int {bit}");
-
- for (int j = 0; j < 4; j++)
- {
- bigIntBytes[4 * i + j] = intBytes[j];
- }
+ bigIntBytes[4 * i + j] = intBytes[j];
}
- bigInt = new BigInteger(bigIntBytes);
+ }
+ bigInt = new BigInteger(bigIntBytes);
#else
- byte[] bigIntBytes = new byte[12];
- for (int i = 0; i < 3; i++)
+ byte[] bigIntBytes = new byte[13];
+ for (int i = 0; i < 3; i++)
+ {
+ int bit = decimalBits[i];
+ byte[] intBytes = BitConverter.GetBytes(bit);
+ for (int j = 0; j < intBytes.Length; j++)
{
- int bit = decimalBits[i];
- byte[] intBytes = BitConverter.GetBytes(bit);
- for (int j = 0; j < intBytes.Length; j++)
- {
- bigIntBytes[4 * i + j] = intBytes[j];
- }
+ bigIntBytes[4 * i + j] = intBytes[j];
}
- bigInt = new BigInteger(bigIntBytes);
+ }
+ bigInt = new BigInteger(bigIntBytes);
#endif
if (value < 0)
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs
index 68f8ee02b1..4c4e653726 100644
--- a/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs
+++ b/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs
@@ -97,6 +97,26 @@ namespace Apache.Arrow.Tests
Assert.Equal(-large, array.GetValue(1));
}
+ [Fact]
+ public void AppendMaxAndMinDecimal()
+ {
+ // Arrange
+ var builder = new Decimal128Array.Builder(new Decimal128Type(29, 0));
+
+ // Act
+ builder.Append(Decimal.MaxValue);
+ builder.Append(Decimal.MinValue);
+ builder.Append(Decimal.MaxValue - 10);
+ builder.Append(Decimal.MinValue + 10);
+
+ // Assert
+ var array = builder.Build();
+ Assert.Equal(Decimal.MaxValue, array.GetValue(0));
+ Assert.Equal(Decimal.MinValue, array.GetValue(1));
+ Assert.Equal(Decimal.MaxValue - 10, array.GetValue(2));
+ Assert.Equal(Decimal.MinValue + 10, array.GetValue(3));
+ }
+
[Fact]
public void AppendFractionalDecimal()
{
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs
index 35b68823d9..e63c39d24e 100644
--- a/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs
+++ b/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs
@@ -97,6 +97,26 @@ namespace Apache.Arrow.Tests
Assert.Equal(-large, array.GetValue(1));
}
+ [Fact]
+ public void AppendMaxAndMinDecimal()
+ {
+ // Arrange
+ var builder = new Decimal256Array.Builder(new Decimal256Type(29, 0));
+
+ // Act
+ builder.Append(Decimal.MaxValue);
+ builder.Append(Decimal.MinValue);
+ builder.Append(Decimal.MaxValue - 10);
+ builder.Append(Decimal.MinValue + 10);
+
+ // Assert
+ var array = builder.Build();
+ Assert.Equal(Decimal.MaxValue, array.GetValue(0));
+ Assert.Equal(Decimal.MinValue, array.GetValue(1));
+ Assert.Equal(Decimal.MaxValue - 10, array.GetValue(2));
+ Assert.Equal(Decimal.MinValue + 10, array.GetValue(3));
+ }
+
[Fact]
public void AppendFractionalDecimal()
{