Skip to content

Commit

Permalink
Fixed serialization of small negative decimals #33
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkWanderer committed Jun 1, 2020
1 parent fad9ae5 commit 108de12
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
4 changes: 4 additions & 0 deletions ClickHouse.Client.Tests/TestUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public static IEnumerable<DataTypeSample> GetDataTypeSamples()
yield return new DataTypeSample("Decimal64(7)", typeof(decimal), "toDecimal64(1.2345, 7)", new decimal(1.2345));
yield return new DataTypeSample("Decimal128(9)", typeof(decimal), "toDecimal128(12.34, 9)", new decimal(12.34));

yield return new DataTypeSample("Decimal32(3)", typeof(decimal), "toDecimal32(-123.45, 3)", new decimal(-123.45));
yield return new DataTypeSample("Decimal64(7)", typeof(decimal), "toDecimal64(-1.2345, 7)", new decimal(-1.2345));
yield return new DataTypeSample("Decimal128(9)", typeof(decimal), "toDecimal128(-12.34, 9)", new decimal(-12.34));

yield return new DataTypeSample("Array(Int32)", typeof(int[]), "array(1, 2, 3)", new[] { 1, 2, 3 });

yield return new DataTypeSample("Nullable(Int32)", typeof(int?), "toInt32OrNull('123')", 123);
Expand Down
15 changes: 12 additions & 3 deletions ClickHouse.Client/Formats/BinaryStreamWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,18 @@ public void WriteValue(object data, ClickHouseType databaseType)
case ClickHouseTypeCode.Decimal:
var dti = (DecimalType)databaseType;
var value = new BigInteger(MathUtils.ShiftDecimalPlaces(Convert.ToDecimal(data), dti.Scale));
var dbytes = new byte[dti.Size];
value.ToByteArray().CopyTo(dbytes, 0);
writer.Write(dbytes);
var biBytes = value.ToByteArray();
var decimalBytes = new byte[dti.Size];
biBytes.CopyTo(decimalBytes, 0);

// If a negative BigInteger is not long enough to fill the whole buffer, the remainder needs to be filled with 0xFF
if (value < 0)
{
for (int i = biBytes.Length; i < dti.Size; i++)
decimalBytes[i] = 0xFF;
}

writer.Write(decimalBytes);
break;

case ClickHouseTypeCode.String:
Expand Down

0 comments on commit 108de12

Please sign in to comment.