Skip to content

Commit

Permalink
fix & add test units
Browse files Browse the repository at this point in the history
  • Loading branch information
Davoud Eshtehari committed Jul 20, 2021
1 parent 68fc259 commit 50a9daa
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,63 @@ internal decimal Decimal
{
if (_value._numericInfo._data4 != 0 || _value._numericInfo._scale > 28)
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
if (_value._numericInfo._scale > 0)
{
SqlDecimal sqlValue = new(_value._numericInfo._precision,
_value._numericInfo._scale,
_value._numericInfo._positive,
_value._numericInfo._data1,
_value._numericInfo._data2,
_value._numericInfo._data3,
_value._numericInfo._data4);

// Remove trail zeros after the point from the end to calculate the valuable floating part
string[] valueParts = sqlValue.ToString().TrimEnd('0').Split('.');
int scale = valueParts[1].Length;
int precision = valueParts[0].Length + scale + (sqlValue.IsPositive ? 0 : -1);

// Out of range
if ((precision > 29 || scale > 28) && !(precision == 29 && scale == 28))
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
}
else
{
// Precision could be 28 or 29
// ex: (precision == 29 && scale == 28)
// valid: (+/-)7.1234567890123456789012345678
// invalid: (+/-)8.1234567890123456789012345678
bool tryMaxPrec = (valueParts[0].Length == 1 || (valueParts[0].Length == 2 && !_value._numericInfo._positive));
int precConvert = 29;
int scaleConvert;

if (!tryMaxPrec && precision != 29)
{
precConvert = 28;
}
scaleConvert = precConvert - (precision - scale);

try
{
return SqlDecimal.ConvertToPrecScale(sqlValue, precConvert, scaleConvert).Value;
}
catch (OverflowException)
{
if (tryMaxPrec && scale < 28)
{
return SqlDecimal.ConvertToPrecScale(sqlValue, precConvert - 1, scaleConvert).Value;
}
else
{
throw;
}
}
}
}
else
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
}
}
return new decimal(_value._numericInfo._data1, _value._numericInfo._data2, _value._numericInfo._data3, !_value._numericInfo._positive, _value._numericInfo._scale);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,63 @@ internal decimal Decimal
{
if (_value._numericInfo._data4 != 0 || _value._numericInfo._scale > 28)
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
if (_value._numericInfo._scale > 0)
{
SqlDecimal sqlValue = new(_value._numericInfo._precision,
_value._numericInfo._scale,
_value._numericInfo._positive,
_value._numericInfo._data1,
_value._numericInfo._data2,
_value._numericInfo._data3,
_value._numericInfo._data4);

// Remove trail zeros after the point from the end to calculate the valuable floating part
string[] valueParts = sqlValue.ToString().TrimEnd('0').Split('.');
int scale = valueParts[1].Length;
int precision = valueParts[0].Length + scale + (sqlValue.IsPositive ? 0 : -1);

// Out of range
if ((precision > 29 || scale > 28) && !(precision == 29 && scale == 28))
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
}
else
{
// Precision could be 28 or 29
// ex: (precision == 29 && scale == 28)
// valid: (+/-)7.1234567890123456789012345678
// invalid: (+/-)8.1234567890123456789012345678
bool tryMaxPrec = (valueParts[0].Length == 1 || (valueParts[0].Length == 2 && !_value._numericInfo._positive));
int precConvert = 29;
int scaleConvert;

if (!tryMaxPrec && precision != 29)
{
precConvert = 28;
}
scaleConvert = precConvert - (precision - scale);

try
{
return SqlDecimal.ConvertToPrecScale(sqlValue, precConvert, scaleConvert).Value;
}
catch (OverflowException)
{
if (tryMaxPrec && scale < 28)
{
return SqlDecimal.ConvertToPrecScale(sqlValue, precConvert - 1, scaleConvert).Value;
}
else
{
throw;
}
}
}
}
else
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
}
}
return new decimal(_value._numericInfo._data1, _value._numericInfo._data2, _value._numericInfo._data3, !_value._numericInfo._positive, _value._numericInfo._scale);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,66 @@ public static void TestParametersWithDatatablesTVPInsert()
}

#region Scaled Decimal Parameter & TVP Test
[ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
[InlineData("CAST(7.1234567890123456789012345678 as decimal(38, 35))", "7.1234567890123456789012345678")]
[InlineData("CAST(-7.1234567890123456789012345678 as decimal(38, 35))", "-7.1234567890123456789012345678")]
[InlineData("CAST(-0.1234567890123456789012345678 as decimal(38, 35))", "-0.1234567890123456789012345678")]
[InlineData("CAST(4210862852.86 as decimal(38, 20))", "4210862852.860000000000000000")]
[InlineData("CAST(0 as decimal(38, 36))", "0.0000000000000000000000000000")]
[InlineData("CAST(79228162514264337593543950335 as decimal(38, 9))", "79228162514264337593543950335")]
[InlineData("CAST(-79228162514264337593543950335 as decimal(38, 9))", "-79228162514264337593543950335")]
[InlineData("CAST(0.4210862852 as decimal(38, 38))", "0.4210862852000000000000000000")]
[InlineData("CAST(0.1234567890123456789012345678 as decimal(38, 38))", "0.1234567890123456789012345678")]
[InlineData("CAST(249454727.14678312032280248320 as decimal(38, 20))", "249454727.14678312032280248320")]
[InlineData("CAST(3961408124790879675.7769715711 as decimal(38, 10))", "3961408124790879675.7769715711")]
[InlineData("CAST(3961408124790879675776971571.1 as decimal(38, 1))", "3961408124790879675776971571.1")]
[InlineData("CAST(79228162514264337593543950335 as decimal(38, 0))", "79228162514264337593543950335")]
[InlineData("CAST(-79228162514264337593543950335 as decimal(38, 0))", "-79228162514264337593543950335")]
[InlineData("CAST(0.0000000000000000000000000001 as decimal(38, 38))", "0.0000000000000000000000000001")]
[InlineData("CAST(-0.0000000000000000000000000001 as decimal(38, 38))", "-0.0000000000000000000000000001")]
public static void SqlDecimalConvertToDecimal_TestInRange(string sqlDecimalValue, string expectedDecimalValue)
{
using(SqlConnection cnn = new(s_connString))
{
cnn.Open();
using(SqlCommand cmd = new($"SELECT {sqlDecimalValue} val"))
{
cmd.Connection = cnn;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
Assert.True(rdr.Read(), "SqlDataReader must have a value");
decimal retrunValue = rdr.GetDecimal(0);
Assert.Equal(expectedDecimalValue, retrunValue.ToString());
}
}
}
}

[ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
[InlineData("CAST(7.9999999999999999999999999999 as decimal(38, 35))")]
[InlineData("CAST(8.1234567890123456789012345678 as decimal(38, 35))")]
[InlineData("CAST(-8.1234567890123456789012345678 as decimal(38, 35))")]
[InlineData("CAST(123456789012345678901234567890 as decimal(38, 0))")]
[InlineData("CAST(7922816251426433759354395.9999 as decimal(38, 8))")]
[InlineData("CAST(-7922816251426433759354395.9999 as decimal(38, 8))")]
[InlineData("CAST(0.123456789012345678901234567890 as decimal(38, 36))")]
public static void SqlDecimalConvertToDecimal_TestOutOfRange(string sqlDecimalValue)
{
using (SqlConnection cnn = new(s_connString))
{
cnn.Open();
using (SqlCommand cmd = new($"SELECT {sqlDecimalValue} val"))
{
cmd.Connection = cnn;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
Assert.True(rdr.Read(), "SqlDataReader must have a value");
Assert.Throws<OverflowException>(() => rdr.GetDecimal(0));
}
}
}
}

[Theory]
[ClassData(typeof(ConnectionStringsProvider))]
public static void TestScaledDecimalParameter_CommandInsert(string connectionString, bool truncateScaledDecimal)
Expand Down

0 comments on commit 50a9daa

Please sign in to comment.