Skip to content

Commit

Permalink
[release/6.0] Query: Don't add grouping key to projection when Distin…
Browse files Browse the repository at this point in the history
…ct is applied (#28143)
  • Loading branch information
smitpatel authored Jun 14, 2022
1 parent 6b5ad88 commit 0ac98ef
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2996,7 +2996,10 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal()
}
}

if (subquery._groupBy.Count > 0)
if (subquery._groupBy.Count > 0
&& (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue28039", out var enabled28039)
&& enabled28039
|| !subquery.IsDistinct))
{
foreach (var key in subquery._groupBy)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,23 @@ from g in grouping
entryCount: 63);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Join_GroupBy_Aggregate_distinct_single_join(bool async)
{
return AssertQuery(
async,
ss =>
from c in ss.Set<Customer>()
join a in ss.Set<Order>().GroupBy(o => new { o.CustomerID, o.OrderDate.Value.Year })
.Where(g => g.Count() > 5)
.Select(g => new { CustomerID = g.Key.CustomerID, LastOrderID = g.Max(o => o.OrderID) })
.Distinct()
on c.CustomerID equals a.CustomerID
select new { c, a.LastOrderID },
entryCount: 31);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Join_GroupBy_Aggregate_with_left_join(bool async)
Expand Down
64 changes: 64 additions & 0 deletions test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -986,5 +986,69 @@ protected class Child26744
public DateTime? SomeOtherNullableDateTime { get; set; }
public Parent26744 Parent { get; set; }
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task Pushdown_does_not_add_grouping_key_to_projection_when_distinct_is_applied(bool async)
{
var contextFactory = await InitializeAsync<Context28039>();
using var db = contextFactory.CreateContext();


var queryResults = (from i in db.IndexData.Where(a => a.Parcel == "some condition")
.Select(a => new SearchResult { ParcelNumber = a.Parcel, RowId = a.RowId })
group i by new { i.ParcelNumber, i.RowId } into grp
where grp.Count() == 1
select grp.Key.ParcelNumber).Distinct();

var jsonLookup = (from dcv in db.TableData.Where(a => a.TableId == 123)
join wos in queryResults
on dcv.ParcelNumber equals wos
orderby dcv.ParcelNumber
select dcv.JSON).Take(123456);


var result = async
? await jsonLookup.ToListAsync()
: jsonLookup.ToList();
}

protected class Context28039 : DbContext
{
public Context28039(DbContextOptions options)
: base(options)
{
}

public DbSet<IndexData> IndexData { get; set; }
public DbSet<TableData> TableData { get; set; }
}

public class TableData : EntityBase
{
public int TableId { get; set; }
public string ParcelNumber { get; set; }
public short RowId { get; set; }
public string JSON { get; set; }

}

public abstract class EntityBase
{
[Key]
public int ID { get; set; }
}
public class IndexData : EntityBase
{
public string Parcel { get; set; }
public int RowId { get; set; }
}

internal class SearchResult
{
public string ParcelNumber { get; set; }
public int RowId { get; set; }
public string DistinctValue { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,21 @@ HAVING COUNT(*) > 5
INNER JOIN [Orders] AS [o0] ON [c].[CustomerID] = [o0].[CustomerID]");
}

public override async Task Join_GroupBy_Aggregate_distinct_single_join(bool async)
{
await base.Join_GroupBy_Aggregate_distinct_single_join(async);

AssertSql(
@"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[LastOrderID]
FROM [Customers] AS [c]
INNER JOIN (
SELECT DISTINCT [o].[CustomerID], MAX([o].[OrderID]) AS [LastOrderID]
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID], DATEPART(year, [o].[OrderDate])
HAVING COUNT(*) > 5
) AS [t] ON [c].[CustomerID] = [t].[CustomerID]");
}

public override async Task Join_GroupBy_Aggregate_with_left_join(bool async)
{
await base.Join_GroupBy_Aggregate_with_left_join(async);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,5 +297,25 @@ WHERE [c].[SomeNullableDateTime] IS NULL
) AS [t0] ON [p].[Id] = [t0].[ParentId]
WHERE [t0].[SomeOtherNullableDateTime] IS NOT NULL");
}

public override async Task Pushdown_does_not_add_grouping_key_to_projection_when_distinct_is_applied(bool async)
{
await base.Pushdown_does_not_add_grouping_key_to_projection_when_distinct_is_applied(async);

AssertSql(
@"@__p_0='123456'
SELECT TOP(@__p_0) [t].[JSON]
FROM [TableData] AS [t]
INNER JOIN (
SELECT DISTINCT [i].[Parcel]
FROM [IndexData] AS [i]
WHERE [i].[Parcel] = N'some condition'
GROUP BY [i].[Parcel], [i].[RowId]
HAVING COUNT(*) = 1
) AS [t0] ON [t].[ParcelNumber] = [t0].[Parcel]
WHERE [t].[TableId] = 123
ORDER BY [t].[ParcelNumber]");
}
}
}

0 comments on commit 0ac98ef

Please sign in to comment.