Skip to content

Commit

Permalink
Fix #4308 - InvalidCastException for decimal without significant digits
Browse files Browse the repository at this point in the history
  • Loading branch information
mikary committed Feb 2, 2016
1 parent aaec0ba commit a75bbef
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace Microsoft.EntityFrameworkCore.Storage
public class RelationalSqlGenerationHelper : ISqlGenerationHelper
{
protected virtual string FloatingPointFormat => "{0}E0";
protected virtual int DecimalPrecision => 18;
protected virtual string DecimalFormat => "0.0".PadRight(DecimalPrecision - 1, '#');
protected virtual string DateTimeFormat => @"yyyy-MM-dd HH\:mm\:ss.fffffff";
protected virtual string DateTimeOffsetFormat => @"yyyy-MM-dd HH\:mm\:ss.fffffffzzz";

Expand Down Expand Up @@ -68,7 +70,7 @@ protected virtual string GenerateLiteralValue(byte value)
=> value.ToString();

protected virtual string GenerateLiteralValue(decimal value)
=> string.Format(value.ToString(CultureInfo.InvariantCulture));
=> string.Format(value.ToString(DecimalFormat, CultureInfo.InvariantCulture));

protected virtual string GenerateLiteralValue(double value)
=> string.Format(CultureInfo.InvariantCulture, FloatingPointFormat, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3227,6 +3227,24 @@ public virtual void Sum_with_arg_expression()
AssertQuery<Order>(os => os.Sum(o => o.OrderID + o.OrderID));
}

[ConditionalFact]
public virtual void Sum_with_division_on_decimal()
{
AssertQuery<OrderDetail>(
ods => ods.Sum(od => od.Quantity / 2.09m),
asserter: (l2o, ef)
=> Assert.InRange((decimal)l2o - (decimal)ef, -0.1m, 0.1m));
}

[ConditionalFact]
public virtual void Sum_with_division_on_decimal_no_significant_digits()
{
AssertQuery<OrderDetail>(
ods => ods.Sum(od => od.Quantity / 2m),
asserter: (l2o, ef)
=> Assert.InRange((decimal)l2o - (decimal)ef, -0.1m, 0.1m));
}

[ConditionalFact]
public virtual void Min_with_no_arg()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [Order Details] AS [od]
WHERE ([od].[UnitPrice] > 10) AND ([o].[OrderID] = [od].[OrderID]))
WHERE ([od].[UnitPrice] > 10.0) AND ([o].[OrderID] = [od].[OrderID]))
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
), CASE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,22 @@ public override void Sum_with_binary_expression()
Sql);
}

public override void Sum_with_division_on_decimal()
{
base.Sum_with_division_on_decimal();

Assert.Equal(@"SELECT SUM([od].[Quantity] / 2.09)
FROM [Order Details] AS [od]", Sql);
}

public override void Sum_with_division_on_decimal_no_significant_digits()
{
base.Sum_with_division_on_decimal_no_significant_digits();

Assert.Equal(@"SELECT SUM([od].[Quantity] / 2.0)
FROM [Order Details] AS [od]", Sql);
}

public override void Min_with_no_arg()
{
base.Min_with_no_arg();
Expand Down Expand Up @@ -3683,7 +3699,7 @@ public override void Where_math_abs3()
Assert.Equal(
@"SELECT [od].[OrderID], [od].[ProductID], [od].[Discount], [od].[Quantity], [od].[UnitPrice]
FROM [Order Details] AS [od]
WHERE ABS([od].[UnitPrice]) > 10",
WHERE ABS([od].[UnitPrice]) > 10.0",
Sql);
}

Expand Down Expand Up @@ -3716,7 +3732,7 @@ public override void Where_math_ceiling2()
Assert.Equal(
@"SELECT [od].[OrderID], [od].[ProductID], [od].[Discount], [od].[Quantity], [od].[UnitPrice]
FROM [Order Details] AS [od]
WHERE CEILING([od].[UnitPrice]) > 10",
WHERE CEILING([od].[UnitPrice]) > 10.0",
Sql);
}

Expand All @@ -3727,7 +3743,7 @@ public override void Where_math_floor()
Assert.Equal(
@"SELECT [od].[OrderID], [od].[ProductID], [od].[Discount], [od].[Quantity], [od].[UnitPrice]
FROM [Order Details] AS [od]
WHERE FLOOR([od].[UnitPrice]) > 10",
WHERE FLOOR([od].[UnitPrice]) > 10.0",
Sql);
}

Expand Down Expand Up @@ -3766,7 +3782,7 @@ public override void Where_math_round()
Assert.Equal(
@"SELECT [od].[OrderID], [od].[ProductID], [od].[Discount], [od].[Quantity], [od].[UnitPrice]
FROM [Order Details] AS [od]
WHERE ROUND([od].[UnitPrice], 0) > 10",
WHERE ROUND([od].[UnitPrice], 0) > 10.0",
Sql);
}

Expand All @@ -3777,7 +3793,7 @@ public override void Where_math_truncate()
Assert.Equal(
@"SELECT [od].[OrderID], [od].[ProductID], [od].[Discount], [od].[Quantity], [od].[UnitPrice]
FROM [Order Details] AS [od]
WHERE ROUND([od].[UnitPrice], 0, 1) > 10",
WHERE ROUND([od].[UnitPrice], 0, 1) > 10.0",
Sql);
}

Expand Down Expand Up @@ -3871,35 +3887,35 @@ public override void Convert_ToDecimal()
Assert.Equal(
@"SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(tinyint, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(tinyint, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(decimal, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(decimal, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(float, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(float, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(float, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(float, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(smallint, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(smallint, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(int, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(int, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(bigint, [o].[OrderID] % 1)) >= 0)
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(bigint, [o].[OrderID] % 1)) >= 0.0)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(nvarchar, [o].[OrderID] % 1)) >= 0)",
WHERE ([o].[CustomerID] = 'ALFKI') AND (CONVERT(decimal, CONVERT(nvarchar, [o].[OrderID] % 1)) >= 0.0)",
Sql);
}

Expand Down

0 comments on commit a75bbef

Please sign in to comment.