Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ [new OrderingExpression(
// cast the argument so SQL computes a floating-point AVG, not integer division.
[NeedsFloatCast(expr, method.ReturnType)
? _sqlExpressionFactory.ApplyDefaultTypeMapping(
_sqlExpressionFactory.Convert(expr, method.ReturnType))
_sqlExpressionFactory.Convert(expr, typeof(double)))
: expr],
spec, method.ReturnType),

Expand Down Expand Up @@ -209,7 +209,7 @@ private WindowFunctionSqlExpression MakeNavigation(
// SQL Server performs integer division for AVG(int) — cast the argument when the
// CLR return type is floating-point but the expression is an integer type.
private static bool NeedsFloatCast(SqlExpression expr, Type returnType) =>
returnType == typeof(double)
(returnType == typeof(double) || returnType == typeof(double?))
&& expr.Type is var t
&& (t == typeof(int) || t == typeof(long) || t == typeof(int?) || t == typeof(long?));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,31 @@ public async Task Average_IntColumn_ReturnsDouble()
Assert.AreEqual(2.1, results[^1].AvgQty, 0.01);
}

[TestMethod]
public async Task Average_NullableIntColumn_CastsToFloat()
{
var query = Context.Orders
.Select(o => new
{
o.Id,
AvgCustomer = WindowFunction.Average(o.CustomerId,
Window.OrderBy(o.Id)
.RowsBetween(WindowFrameBound.UnboundedPreceding, WindowFrameBound.UnboundedFollowing)),
})
.OrderBy(x => x.Id);

var sql = query.ToQueryString();
StringAssert.Contains(sql, "AVG");
// Float cast renders per-provider: CAST(... AS ...) on most, ::double precision on PostgreSQL.
Assert.IsTrue(sql.Contains("CAST(") || sql.Contains("::"),
$"AVG argument should be cast to floating point, but no cast was found in: {sql}");

var results = await query.ToListAsync();
Assert.AreEqual(10, results.Count);
// AVG of CustomerId (five 1s + five 2s = 15/10) must be 1.5, not integer-divided to 1.
Assert.AreEqual(1.5, results[0].AvgCustomer!.Value, 0.01);
}

[TestMethod]
public async Task Sum_WithoutFrame_UsesDefaultFrame()
{
Expand Down
Loading