Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
ports: [ "2135:2135", "2136:2136", "8765:8765" ]
env:
YDB_LOCAL_SURVIVE_RESTART: true
YDB_FEATURE_FLAGS: enable_parameterized_decimal
options: '--name ydb-local -h localhost'

steps:
Expand Down
3 changes: 2 additions & 1 deletion src/Ydb.Sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- Fixed bug: interval value parsing in microseconds and double instead of ticks.
- Feat ADO.NET: decimal type with arbitrary precision/scale ([#498](https://github.com/ydb-platform/ydb-dotnet-sdk/issues/498)).
- Fixed bug: interval value parsing in microseconds and double instead of ticks ([#497](https://github.com/ydb-platform/ydb-dotnet-sdk/issues/497)).
- ADO.NET: Changed `IBulkUpsertImporter.AddRowAsync` signature: `object?[] row` → `params object[]`.

## v0.21.0
Expand Down
2 changes: 1 addition & 1 deletion src/Ydb.Sdk/src/Ado/Schema/SchemaUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal static class SchemaUtils
Type.Types.PrimitiveTypeId.String => "Bytes",
_ => type.TypeId.ToString()
},
Type.TypeOneofCase.DecimalType => "Decimal(22, 9)",
Type.TypeOneofCase.DecimalType => $"Decimal({type.DecimalType.Precision}, {type.DecimalType.Scale})",
_ => "Unknown"
};

Expand Down
20 changes: 17 additions & 3 deletions src/Ydb.Sdk/src/Ado/YdbParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Data;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
using Google.Protobuf.WellKnownTypes;
using Ydb.Sdk.Value;

namespace Ydb.Sdk.Ado;
Expand Down Expand Up @@ -30,8 +31,6 @@ public sealed class YdbParameter : DbParameter
{ DbType.Byte, YdbValue.MakeOptionalUint8() },
{ DbType.DateTime2, YdbValue.MakeOptionalTimestamp() },
{ DbType.DateTimeOffset, YdbValue.MakeOptionalTimestamp() },
{ DbType.Decimal, YdbValue.MakeOptionalDecimal() },
{ DbType.Currency, YdbValue.MakeOptionalDecimal() },
{ DbType.Guid, YdbValue.MakeOptionalUuid() }
};

Expand Down Expand Up @@ -93,10 +92,23 @@ public override string SourceColumn
public override bool SourceColumnNullMapping { get; set; }
public override int Size { get; set; }

public override byte Precision { get; set; }
public override byte Scale { get; set; }

internal YdbValue YdbValue => Value switch
{
YdbValue ydbValue => ydbValue,
null or DBNull when YdbNullByDbType.TryGetValue(DbType, out var value) => value,
null or DBNull when DbType is DbType.Decimal or DbType.Currency => Precision == 0 && Scale == 0
? YdbValue.MakeOptionalDecimal()
: new YdbValue(
new Type
{
OptionalType = new OptionalType
{ Item = new Type { DecimalType = new DecimalType { Precision = Precision, Scale = Scale } } }
},
new Ydb.Value { NullFlagValue = new NullValue() }
),
string valueString when DbType is DbType.String or DbType.AnsiString or DbType.AnsiStringFixedLength
or DbType.StringFixedLength or DbType.Object => YdbValue.MakeUtf8(valueString),
bool boolValue when DbType is DbType.Boolean or DbType.Object => YdbValue.MakeBool(boolValue),
Expand Down Expand Up @@ -126,7 +138,9 @@ string valueString when DbType is DbType.String or DbType.AnsiString or DbType.A
},
long longValue when DbType is DbType.Int64 or DbType.Object => YdbValue.MakeInt64(longValue),
decimal decimalValue when DbType is DbType.Decimal or DbType.Currency or DbType.Object =>
YdbValue.MakeDecimal(decimalValue),
Precision == 0 && Scale == 0
? YdbValue.MakeDecimal(decimalValue)
: YdbValue.MakeDecimalWithPrecision(decimalValue, precision: Precision, scale: Scale),
ulong ulongValue when DbType is DbType.UInt64 or DbType.Object => YdbValue.MakeUint64(ulongValue),
uint uintValue => DbType switch
{
Expand Down
2 changes: 1 addition & 1 deletion src/Ydb.Sdk/src/Value/YdbValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private static string ToYql(Type type) =>
type.TypeCase switch
{
Type.TypeOneofCase.TypeId => type.TypeId.ToString(),
Type.TypeOneofCase.DecimalType => "Decimal(22, 9)",
Type.TypeOneofCase.DecimalType => $"Decimal({type.DecimalType.Precision}, {type.DecimalType.Scale})",
Type.TypeOneofCase.OptionalType => $"{ToYql(type.OptionalType.Item)}?",
Type.TypeOneofCase.ListType => $"List<{ToYql(type.ListType.Item)}>",
Type.TypeOneofCase.VoidType => "Void",
Expand Down
80 changes: 14 additions & 66 deletions src/Ydb.Sdk/src/Value/YdbValueBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,86 +86,33 @@ public static YdbValue MakeUuid(Guid guid)
new Ydb.Value { Low128 = low, High128 = high });
}

private static byte GetDecimalScale(decimal value)
public static YdbValue MakeDecimalWithPrecision(decimal value, uint precision, uint scale)
{
var bits = decimal.GetBits(value);
var flags = bits[3];
var scale = (byte)((flags >> 16) & 0x7F);
return scale;
}

private static uint GetDecimalPrecision(decimal value)
{
var bits = decimal.GetBits(value);
value = new decimal(lo: bits[0], mid: bits[1], hi: bits[2], isNegative: false, scale: 0);

var precision = 0u;
while (value != decimal.Zero)
{
value = Math.Round(value / 10);
precision++;
}

return precision;
}
value *= 1.00000000000000000000000000000m; // 29 zeros, max supported by c# decimal
value = Math.Round(value, (int)scale);

private static Ydb.Value MakeDecimalValue(decimal value)
{
var type = new Type { DecimalType = new DecimalType { Scale = scale, Precision = precision } };
var bits = decimal.GetBits(value);

var low64 = ((ulong)(uint)bits[1] << 32) + (uint)bits[0];
var high64 = (ulong)(uint)bits[2];
var lo = ((ulong)bits[1] << 32) + (uint)bits[0];
var hi = (ulong)bits[2];

unchecked
{
// make value negative
if (value < 0)
{
low64 = ~low64;
high64 = ~high64;
lo = ~lo;
hi = ~hi;

if (low64 == (ulong)-1L)
if (lo == (ulong)-1L)
{
high64 += 1;
hi += 1;
}

low64 += 1;
lo += 1;
}
}

return new Ydb.Value
{
Low128 = low64,
High128 = high64
};
}

public static YdbValue MakeDecimalWithPrecision(decimal value, uint? precision = null, uint? scale = null)
{
var valueScale = GetDecimalScale(value);
var valuePrecision = GetDecimalPrecision(value);
scale ??= GetDecimalScale(value);
precision ??= valuePrecision;

if ((int)valuePrecision - valueScale > (int)precision - scale)
{
throw new InvalidCastException(
$"Decimal with precision ({valuePrecision}, {valueScale}) can't fit into ({precision}, {scale})");
}

// multiply for fill value with trailing zeros
// ex: 123.45 -> 123.4500...00
value *= 1.00000000000000000000000000000m; // 29 zeros, max supported by c# decimal
value = Math.Round(value, (int)scale);

var type = new Type
{
DecimalType = new DecimalType { Scale = (uint)scale, Precision = (uint)precision }
};

var ydbValue = MakeDecimalValue(value);

return new YdbValue(type, ydbValue);
return new YdbValue(type, new Ydb.Value { Low128 = lo, High128 = hi });
}

public static YdbValue MakeDecimal(decimal value) => MakeDecimalWithPrecision(value, 22, 9);
Expand All @@ -175,7 +122,8 @@ private static YdbValue MakeOptional(YdbValue value) =>
new Type { OptionalType = new OptionalType { Item = value._protoType } },
value.TypeId != YdbTypeId.OptionalType
? value._protoValue
: new Ydb.Value { NestedValue = value._protoValue });
: new Ydb.Value { NestedValue = value._protoValue }
);

// TODO: MakeEmptyList with complex types
public static YdbValue MakeEmptyList(YdbTypeId typeId) =>
Expand Down
29 changes: 13 additions & 16 deletions src/Ydb.Sdk/src/Value/YdbValueParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,31 +150,28 @@ public Guid GetUuid()
public decimal GetDecimal()
{
EnsureType(Type.TypeOneofCase.DecimalType);
var low64 = _protoValue.Low128;
var high64 = _protoValue.High128;

var lo = _protoValue.Low128;
var hi = _protoValue.High128;
var scale = _protoType.DecimalType.Scale;

var isNegative = false;
var isNegative = (hi & 0x8000_0000_0000_0000UL) != 0;

unchecked
{
if (high64 >> 63 == 1) // if negative
if (isNegative)
{
isNegative = true;
if (low64 == 0)
{
high64 -= 1;
}
if (lo == 0)
hi--;

low64 -= 1;

low64 = ~low64;
high64 = ~high64;
lo--;
lo = ~lo;
hi = ~hi;
}
}

return new decimal((int)low64, (int)(low64 >> 32), (int)high64, isNegative, (byte)scale);
if (hi >> 32 != 0)
throw new OverflowException("Value does not fit into decimal");

return new decimal((int)lo, (int)(lo >> 32), (int)hi, isNegative, (byte)scale);
}

public bool? GetOptionalBool() => GetOptional()?.GetBool();
Expand Down
12 changes: 2 additions & 10 deletions src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Value/YdbValueUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,33 +275,25 @@
Assert.Null(YdbValue.MakeOptionalDecimal().GetOptionalDecimal());
Assert.Null((decimal?)(YdbValue)(decimal?)null);

Assert.Equal("Decimal with precision (30, 0) can't fit into (22, 9)",

Check failure on line 278 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Value/YdbValueUnitTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 9.0.x)

Ydb.Sdk.Ado.Tests.Value.BasicUnitTests.DecimalType

Assert.Throws() Failure: No exception was thrown Expected: typeof(System.InvalidCastException)

Check failure on line 278 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Value/YdbValueUnitTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 8.0.x)

Ydb.Sdk.Ado.Tests.Value.BasicUnitTests.DecimalType

Assert.Throws() Failure: No exception was thrown Expected: typeof(System.InvalidCastException)

Check failure on line 278 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Value/YdbValueUnitTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 8.0.x)

Ydb.Sdk.Ado.Tests.Value.BasicUnitTests.DecimalType

Assert.Throws() Failure: No exception was thrown Expected: typeof(System.InvalidCastException)

Check failure on line 278 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Value/YdbValueUnitTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 9.0.x)

Ydb.Sdk.Ado.Tests.Value.BasicUnitTests.DecimalType

Assert.Throws() Failure: No exception was thrown Expected: typeof(System.InvalidCastException)
Assert.Throws<InvalidCastException>(() => YdbValue.MakeDecimal(decimal.MaxValue)).Message);
}

[Fact]
public void DecimalTypeWithPrecision()
{
Assert.Equal(12345m, YdbValue.MakeDecimalWithPrecision(12345m).GetDecimal());
Assert.Equal(12345m, YdbValue.MakeDecimal(12345m).GetDecimal());
Assert.Equal(12345m, YdbValue.MakeDecimalWithPrecision(12345m, precision: 5, scale: 0).GetDecimal());
Assert.Equal(12345m, YdbValue.MakeDecimalWithPrecision(12345m, precision: 7, scale: 2).GetDecimal());
Assert.Equal(123.46m, YdbValue.MakeDecimalWithPrecision(123.456m, precision: 5, scale: 2).GetDecimal());
Assert.Equal(-18446744073.709551616m,
YdbValue.MakeDecimalWithPrecision(-18446744073.709551616m).GetDecimal());
YdbValue.MakeDecimal(-18446744073.709551616m).GetDecimal());
Assert.Equal(-18446744073.709551616m,
YdbValue.MakeDecimalWithPrecision(-18446744073.709551616m, precision: 21, scale: 9).GetDecimal());
Assert.Equal(-18446744074m,
YdbValue.MakeDecimalWithPrecision(-18446744073.709551616m, precision: 12, scale: 0).GetDecimal());
Assert.Equal(-184467440730709551616m,
YdbValue.MakeDecimalWithPrecision(-184467440730709551616m, precision: 21, scale: 0).GetDecimal());


Assert.Equal("Decimal with precision (5, 0) can't fit into (4, 0)",
Assert.Throws<InvalidCastException>(() => YdbValue.MakeDecimalWithPrecision(12345m, precision: 4))
.Message);
Assert.Equal("Decimal with precision (5, 0) can't fit into (5, 2)",
Assert.Throws<InvalidCastException>(() => YdbValue.MakeDecimalWithPrecision(12345m, precision: 5, 2))
.Message);
}

[Fact]
Expand Down
39 changes: 39 additions & 0 deletions src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,4 +470,43 @@
ydbCommand.Parameters.AddWithValue("dateOnly", DbType.Date, new DateOnly(2102, 2, 24));
Assert.Equal(new DateTime(2102, 2, 24), await ydbCommand.ExecuteScalarAsync());
}

[Theory]
[InlineData("12345", "12345,0000000000", 22, 9)]
[InlineData("54321", "54321", 5, 0)]
[InlineData("493235.4", "493235,40", 7, 2)]
[InlineData("123,46", "123,46", 5, 2)]
[InlineData("-184467434073,70911616", "-184467434073,7091161600", 35, 10)]
[InlineData("-18446744074", "-18446744074", 12, 0)]
[InlineData("-184467440730709551616", "-184467440730709551616", 21, 0)]
[InlineData("-218446744073,709551616", "-218446744073,7095516160", 22, 10)]
[InlineData(null, null, 22, 9)]
[InlineData(null, null, 35, 9)]
[InlineData(null, null, 35, 0)]
public async Task Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(string? value, string? expected,
byte precision, byte scale)
{
await using var ydbConnection = await CreateOpenConnectionAsync();
var decimalTableName = $"DecimalTable_{Random.Shared.Next()}";
var decimalValue = value == null ? (decimal?)null : decimal.Parse(value);
var ydbCommand = new YdbCommand(ydbConnection)
{
CommandText = $"""
CREATE TABLE {decimalTableName} (
DecimalField Decimal({precision}, {scale}),
PRIMARY KEY (DecimalField)
)
"""
};
await ydbCommand.ExecuteNonQueryAsync();
ydbCommand.CommandText = $"INSERT INTO {decimalTableName}(DecimalField) VALUES (@DecimalField);";
ydbCommand.Parameters.Add(
new YdbParameter("DecimalField", DbType.Decimal, decimalValue)
{ Precision = precision, Scale = scale });
await ydbCommand.ExecuteNonQueryAsync();

ydbCommand.CommandText = $"SELECT DecimalField FROM {decimalTableName}";
Assert.Equal(expected == null ? DBNull.Value : decimal.Parse(expected), await ydbCommand.ExecuteScalarAsync());
ydbCommand.CommandText = "DROP TABLE {decimalTableName};";

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-218446744073

Assert.Equal() Failure: Values differ Expected: -2184467440737095516160 Actual: -2184467440737095516.1600000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-184467434073

Assert.Equal() Failure: Values differ Expected: -1844674340737091161600 Actual: -1844674340737091161.6000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "12345"

Assert.Equal() Failure: Values differ Expected: 123450000000000 Actual: 12345.000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "493235.4"

Assert.Equal() Failure: Values differ Expected: 49323540 Actual: 493235.40

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-218446744073

Assert.Equal() Failure: Values differ Expected: -2184467440737095516160 Actual: -2184467440737095516.1600000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-184467434073

Assert.Equal() Failure: Values differ Expected: -1844674340737091161600 Actual: -1844674340737091161.6000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "12345"

Assert.Equal() Failure: Values differ Expected: 123450000000000 Actual: 12345.000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (latest, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "493235.4"

Assert.Equal() Failure: Values differ Expected: 49323540 Actual: 493235.40

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-218446744073

Assert.Equal() Failure: Values differ Expected: -2184467440737095516160 Actual: -2184467440737095516.1600000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-184467434073

Assert.Equal() Failure: Values differ Expected: -1844674340737091161600 Actual: -1844674340737091161.6000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "12345"

Assert.Equal() Failure: Values differ Expected: 123450000000000 Actual: 12345.000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 8.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "493235.4"

Assert.Equal() Failure: Values differ Expected: 49323540 Actual: 493235.40

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-218446744073

Assert.Equal() Failure: Values differ Expected: -2184467440737095516160 Actual: -2184467440737095516.1600000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "-184467434073

Assert.Equal() Failure: Values differ Expected: -1844674340737091161600 Actual: -1844674340737091161.6000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "12345"

Assert.Equal() Failure: Values differ Expected: 123450000000000 Actual: 12345.000000000

Check failure on line 510 in src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

View workflow job for this annotation

GitHub Actions / ydb-sdk-tests (25.1, 9.0.x)

Ydb.Sdk.Ado.Tests.YdbCommandTests.Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal(value: "493235.4"

Assert.Equal() Failure: Values differ Expected: 49323540 Actual: 493235.40
}
}
Loading