Skip to content

Commit

Permalink
Fix to #8492 - Query: incorrect sql generated for query with owned en…
Browse files Browse the repository at this point in the history
…tities, left join and predicate using inner qsre

Problem was that for queries with owned types that were using GroupJoin-SelectMany-DefaultIfEmpty pattern we were not able to find the owned entity type behind the groupjoin subquery qsre.
Usually (i.e. in case of navigations) we look for the entity type in the lookup on QueryCompilationContext, but if the groupjoin is created manually then this lookup was not populated with entry for the groupjoin subquery.

Fix is to populate the lookup with entry for groupjoin subquery qsre. We do it in nav rewrite, which also populates other entries for owned types.
  • Loading branch information
maumar committed Jul 6, 2017
1 parent b7e6011 commit 6187a7a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,7 @@ private class NavigationRewritingQueryModelVisitor : ExpressionTransformingQuery
{
private readonly CollectionNavigationSubqueryInjector _subqueryInjector;
private readonly bool _navigationExpansionSubquery;
private readonly EntityQueryModelVisitor _queryModelVisitor;

public AdditionalFromClause AdditionalFromClauseBeingProcessed { get; private set; }

Expand All @@ -1379,10 +1380,19 @@ public NavigationRewritingQueryModelVisitor(
{
_subqueryInjector = new CollectionNavigationSubqueryInjector(queryModelVisitor, shouldInject: true);
_navigationExpansionSubquery = navigationExpansionSubquery;
_queryModelVisitor = queryModelVisitor;
}

public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index)
{
// ReSharper disable once PatternAlwaysOfType
if (fromClause.TryGetFlattenedGroupJoinClause()?.JoinClause is JoinClause joinClause
// ReSharper disable once PatternAlwaysOfType
&& _queryModelVisitor.QueryCompilationContext.FindEntityType(joinClause) is IEntityType entityType)
{
_queryModelVisitor.QueryCompilationContext.AddOrUpdateMapping(fromClause, entityType);
}

var oldAdditionalFromClause = AdditionalFromClauseBeingProcessed;
AdditionalFromClauseBeingProcessed = fromClause;
fromClause.TransformExpressions(TransformingVisitor.Visit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,41 @@ public override void Nested_group_join_with_take()
base.Nested_group_join_with_take();
}

[ConditionalFact(Skip = "issue #8492")]
[ConditionalFact]
public override void Explicit_GroupJoin_in_subquery_with_unrelated_projection2()
{
base.Explicit_GroupJoin_in_subquery_with_unrelated_projection2();

AssertSql(
@"SELECT [t1].[Id]
FROM (
SELECT DISTINCT [l1].*
FROM [Level1] AS [l1]
LEFT JOIN (
SELECT [t].*
FROM [Level1] AS [t]
WHERE [t].[Id] IS NOT NULL
) AS [t0] ON [l1].[Id] = [t0].[OneToOne_Required_PK_Level1_Optional_Id]
WHERE ([t0].[OneToOne_Required_PK_Name] <> N'Foo') OR [t0].[OneToOne_Required_PK_Name] IS NULL
) AS [t1]");
}

[ConditionalFact]
public override void Result_operator_nav_prop_reference_optional_via_DefaultIfEmpty()
{
base.Result_operator_nav_prop_reference_optional_via_DefaultIfEmpty();

AssertSql(
@"SELECT SUM(CASE
WHEN [t0].[Id] IS NULL
THEN 0 ELSE [t0].[OneToOne_Required_PK_Level1_Required_Id]
END)
FROM [Level1] AS [l1]
LEFT JOIN (
SELECT [t].*
FROM [Level1] AS [t]
WHERE [t].[Id] IS NOT NULL
) AS [t0] ON [l1].[Id] = [t0].[OneToOne_Required_PK_Level1_Optional_Id]");
}

private void AssertSql(params string[] expected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,5 @@ public override void Nested_group_join_with_take()
{
base.Nested_group_join_with_take();
}

[ConditionalFact(Skip = "issue #8492")]
public override void Explicit_GroupJoin_in_subquery_with_unrelated_projection2()
{
base.Explicit_GroupJoin_in_subquery_with_unrelated_projection2();
}
}
}

0 comments on commit 6187a7a

Please sign in to comment.