Skip to content

Commit

Permalink
Query: Don't add grouping key to projection when Distinct is applied (#…
Browse files Browse the repository at this point in the history
…28072)

Resolves #28039
  • Loading branch information
smitpatel authored May 24, 2022
1 parent 3ff83c4 commit 6fde451
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2993,7 +2993,8 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal()
}
}

if (subquery._groupBy.Count > 0)
if (subquery._groupBy.Count > 0
&& !subquery.IsDistinct)
{
foreach (var key in subquery._groupBy)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,21 @@ from g in grouping
},
entryCount: 63);

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Join_GroupBy_Aggregate_distinct_single_join(bool async)
=> 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 @@ -1134,4 +1134,68 @@ 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 @@ -1589,6 +1589,24 @@ 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], [t0].[LastOrderID]
FROM [Customers] AS [c]
INNER JOIN (
SELECT DISTINCT [t].[CustomerID], MAX([t].[OrderID]) AS [LastOrderID]
FROM (
SELECT [o].[OrderID], [o].[CustomerID], DATEPART(year, [o].[OrderDate]) AS [Year]
FROM [Orders] AS [o]
) AS [t]
GROUP BY [t].[CustomerID], [t].[Year]
HAVING COUNT(*) > 5
) AS [t0] ON [c].[CustomerID] = [t0].[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 @@ -409,4 +409,24 @@ FROM [MyEntities] AS [m]
FROM [MyEntities] AS [m]
WHERE [dbo].[ModifyDate]([m].[SomeDate]) = @__date_0");
}

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 6fde451

Please sign in to comment.