Big decimals support
Big decimals support using custom type poached from public domain Planned features:
- Feature toggle to use regular
decimalvs new class - Type is convertible to normal numeric types and string
TODO
- [x] Fix all inaccuracies in math operations
- [ ] Do a round of optimizations
- [ ] Add config flag for supporting the new decimal
- [x] Implement parsing from text
Ref #137
Hello! If I try to use ClickhouseDecimal as a Dapper parameter to Where. I get an exception "The member DecimalName of type ClickHouse.Client.Numerics.ClickHouseDecimal cannot be used as a parameter value".
var connectionFactory = host.Services.GetService<IClickhouseConnectionFactory>()!;
var text = @"
SELECT *
FROM xxxxxx.dapper_test2
WHERE DecimalName = {DecimalName:decimal128(18)}
;
";
var parameters = new Dictionary<string, object> { { "DecimalName",
new ClickHouseDecimal(BigInteger.Parse("123456789123123450000000000000"), 18)} };
using var con = connectionFactory.GetConnection();
var cmd = new CommandDefinition(text, parameters);
try
{
var res = (await con.QueryAsync<DapperDto3>(cmd)).AsList();
}
catch (Exception e)
{
Console.WriteLine(e);
}
Hi! Scale parameter in new ClickhouseDecimal class can be positive only (ushort). Are you planning to do it also negative to suppot such cases as {mantissa:1, scale=-3} => 1000? Thank
@DmitryLk you need to add a custom type handler to Dapper to be able to handle the new Decimal:
Class definition:
private class ClickHouseDecimalHandler : SqlMapper.TypeHandler<ClickHouseDecimal>
{
public override void SetValue(IDbDataParameter parameter, ClickHouseDecimal value) => parameter.Value = value.ToString(CultureInfo.InvariantCulture);
public override ClickHouseDecimal Parse(object value) => value switch
{
ClickHouseDecimal chd => chd,
IConvertible ic => Convert.ToDecimal(ic),
_ => throw new ArgumentException(nameof(value))
};
}
After that, ClickHouseDecimal works both as parameter and as SELECTable value
var parameters = new Dictionary<string, object> { { "value", new ClickHouseDecimal(1m) } };
var results = await connection.QueryAsync<ClickHouseDecimal>("SELECT {value:Decimal32(3)}", parameters);
Assert.AreEqual(value, results.Single());
Positive-only scale/exponent is by design right now as it matches ClickHouse's type. I'll think about switching back to possibly-negative exponent
Thanks. ClickhouseDecimal parameter with custom handler to Dapper is working
| Package | Line Rate | Branch Rate | Complexity | Health |
|---|---|---|---|---|
| ClickHouse.Client | 86% | 74% | 1036 | ✔ |
| Summary | 86% (1335 / 1561) | 74% (471 / 640) | 1036 | ✔ |
| Package | Line Rate | Branch Rate | Complexity | Health |
|---|---|---|---|---|
| ClickHouse.Client | 86% | 75% | 1082 | ✔ |
| Summary | 86% (1423 / 1651) | 75% (495 / 662) | 1082 | ✔ |