Skip to content

Commit

Permalink
Query: Rename Lateral joins to Cross/Outer Apply
Browse files Browse the repository at this point in the history
Since they don't represent lateral join truly
  • Loading branch information
smitpatel committed Aug 21, 2019
1 parent 3fe29b0 commit 59ce5bf
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 68 deletions.
16 changes: 8 additions & 8 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -674,20 +674,20 @@ protected override Expression VisitCrossJoin(CrossJoinExpression crossJoinExpres
return crossJoinExpression;
}

protected override Expression VisitInnerJoinLateral(InnerJoinLateralExpression innerJoinLateralExpression)
protected override Expression VisitCrossApply(CrossApplyExpression crossApplyExpression)
{
_relationalCommandBuilder.Append("INNER JOIN LATERAL ");
Visit(innerJoinLateralExpression.Table);
_relationalCommandBuilder.Append("CROSS APPLY ");
Visit(crossApplyExpression.Table);

return innerJoinLateralExpression;
return crossApplyExpression;
}

protected override Expression VisitLeftJoinLateral(LeftJoinLateralExpression leftJoinLateralExpression)
protected override Expression VisitOuterApply(OuterApplyExpression outerApplyExpression)
{
_relationalCommandBuilder.Append("LEFT JOIN LATERAL ");
Visit(leftJoinLateralExpression.Table);
_relationalCommandBuilder.Append("OUTER APPLY ");
Visit(outerApplyExpression.Table);

return leftJoinLateralExpression;
return outerApplyExpression;
}

protected override Expression VisitInnerJoin(InnerJoinExpression innerJoinExpression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,13 +742,13 @@ protected override ShapedQueryExpression TranslateSelectMany(
var innerShaperExpression = inner.ShaperExpression;
if (defaultIfEmpty)
{
((SelectExpression)source.QueryExpression).AddLeftJoinLateral(
((SelectExpression)source.QueryExpression).AddOuterApply(
(SelectExpression)inner.QueryExpression, transparentIdentifierType);
innerShaperExpression = MarkShaperNullable(innerShaperExpression);
}
else
{
((SelectExpression)source.QueryExpression).AddInnerJoinLateral(
((SelectExpression)source.QueryExpression).AddCrossApply(
(SelectExpression)inner.QueryExpression, transparentIdentifierType);
}

Expand Down
12 changes: 6 additions & 6 deletions src/EFCore.Relational/Query/SqlExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ protected override Expression VisitExtension(Expression extensionExpression)
case CrossJoinExpression crossJoinExpression:
return VisitCrossJoin(crossJoinExpression);

case InnerJoinLateralExpression innerJoinLateralExpression:
return VisitInnerJoinLateral(innerJoinLateralExpression);
case CrossApplyExpression crossApplyExpression:
return VisitCrossApply(crossApplyExpression);

case LeftJoinLateralExpression leftJoinLateralExpression:
return VisitLeftJoinLateral(leftJoinLateralExpression);
case OuterApplyExpression outerApplyExpression:
return VisitOuterApply(outerApplyExpression);

case ExistsExpression existsExpression:
return VisitExists(existsExpression);
Expand Down Expand Up @@ -101,8 +101,8 @@ protected override Expression VisitExtension(Expression extensionExpression)
protected abstract Expression VisitExists(ExistsExpression existsExpression);
protected abstract Expression VisitIn(InExpression inExpression);
protected abstract Expression VisitCrossJoin(CrossJoinExpression crossJoinExpression);
protected abstract Expression VisitInnerJoinLateral(InnerJoinLateralExpression innerJoinLateralExpression);
protected abstract Expression VisitLeftJoinLateral(LeftJoinLateralExpression leftJoinLateralExpression);
protected abstract Expression VisitCrossApply(CrossApplyExpression crossApplyExpression);
protected abstract Expression VisitOuterApply(OuterApplyExpression outerApplyExpression);
protected abstract Expression VisitFromSql(FromSqlExpression fromSqlExpression);
protected abstract Expression VisitInnerJoin(InnerJoinExpression innerJoinExpression);
protected abstract Expression VisitLeftJoin(LeftJoinExpression leftJoinExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@

namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions
{
public class LeftJoinLateralExpression : JoinExpressionBase
public class CrossApplyExpression : JoinExpressionBase
{
public LeftJoinLateralExpression(TableExpressionBase table)
public CrossApplyExpression(TableExpressionBase table)
: base(table)
{
}

protected override Expression VisitChildren(ExpressionVisitor visitor)
=> Update((TableExpressionBase)visitor.Visit(Table));

public virtual LeftJoinLateralExpression Update(TableExpressionBase table)
public virtual CrossApplyExpression Update(TableExpressionBase table)
=> table != Table
? new LeftJoinLateralExpression(table)
? new CrossApplyExpression(table)
: this;

public override void Print(ExpressionPrinter expressionPrinter)
{
expressionPrinter.Append("LEFT JOIN LATERAL ");
expressionPrinter.Append("CROSS APPLY ");
expressionPrinter.Visit(Table);
}

public override bool Equals(object obj)
=> obj != null
&& (ReferenceEquals(this, obj)
|| obj is LeftJoinLateralExpression leftJoinLateralExpression
&& Equals(leftJoinLateralExpression));
|| obj is CrossApplyExpression crossApplyExpression
&& Equals(crossApplyExpression));

private bool Equals(LeftJoinLateralExpression leftJoinLateralExpression)
=> base.Equals(leftJoinLateralExpression);
private bool Equals(CrossApplyExpression crossApplyExpression)
=> base.Equals(crossApplyExpression);

public override int GetHashCode() => base.GetHashCode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@

namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions
{
public class InnerJoinLateralExpression : JoinExpressionBase
public class OuterApplyExpression : JoinExpressionBase
{
public InnerJoinLateralExpression(TableExpressionBase table)
public OuterApplyExpression(TableExpressionBase table)
: base(table)
{
}

protected override Expression VisitChildren(ExpressionVisitor visitor)
=> Update((TableExpressionBase)visitor.Visit(Table));

public virtual InnerJoinLateralExpression Update(TableExpressionBase table)
public virtual OuterApplyExpression Update(TableExpressionBase table)
=> table != Table
? new InnerJoinLateralExpression(table)
? new OuterApplyExpression(table)
: this;

public override void Print(ExpressionPrinter expressionPrinter)
{
expressionPrinter.Append("INNER JOIN LATERAL ");
expressionPrinter.Append("OUTER APPLY ");
expressionPrinter.Visit(Table);
}

public override bool Equals(object obj)
=> obj != null
&& (ReferenceEquals(this, obj)
|| obj is InnerJoinLateralExpression innerJoinLateralExpression
&& Equals(innerJoinLateralExpression));
|| obj is OuterApplyExpression outerApplyExpression
&& Equals(outerApplyExpression));

private bool Equals(InnerJoinLateralExpression innerJoinLateralExpression)
=> base.Equals(innerJoinLateralExpression);
private bool Equals(OuterApplyExpression outerApplyExpression)
=> base.Equals(outerApplyExpression);

public override int GetHashCode() => base.GetHashCode();
}
Expand Down
28 changes: 14 additions & 14 deletions src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ public Expression AddSingleProjection(ShapedQueryExpression shapedQueryExpressio
var innerSelectExpression = (SelectExpression)shapedQueryExpression.QueryExpression;
innerSelectExpression.ApplyProjection();
var projectionCount = innerSelectExpression.Projection.Count;
AddLeftJoinLateral(innerSelectExpression, null);
AddOuterApply(innerSelectExpression, null);

// Joined SelectExpression may different based on left join or outer apply
// And it will always be SelectExpression because of presence of Take(1)
Expand Down Expand Up @@ -786,7 +786,7 @@ public Expression ApplyCollectionJoin(
}

var joinExpression = joinPredicate == null
? (TableExpressionBase)new LeftJoinLateralExpression(innerSelectExpression.Tables.Single())
? (TableExpressionBase)new OuterApplyExpression(innerSelectExpression.Tables.Single())
: new LeftJoinExpression(innerSelectExpression.Tables.Single(), joinPredicate);
_tables.Add(joinExpression);

Expand Down Expand Up @@ -1028,8 +1028,8 @@ private enum JoinType
InnerJoin,
LeftJoin,
CrossJoin,
InnerJoinLateral,
LeftJoinLateral
CrossApply,
OuterApply
}

private void AddJoin(
Expand All @@ -1038,8 +1038,8 @@ private void AddJoin(
Type transparentIdentifierType,
SqlExpression joinPredicate = null)
{
// Try to convert lateral join to normal join
if (joinType == JoinType.InnerJoinLateral || joinType == JoinType.LeftJoinLateral)
// Try to convert Apply to normal join
if (joinType == JoinType.CrossApply || joinType == JoinType.OuterApply)
{
// Doing for limit only since limit + offset may need sum
var limit = innerSelectExpression.Limit;
Expand Down Expand Up @@ -1080,7 +1080,7 @@ private void AddJoin(
innerSelectExpression.ApplyPredicate(predicate);
}

AddJoin(joinType == JoinType.InnerJoinLateral ? JoinType.InnerJoin : JoinType.LeftJoin,
AddJoin(joinType == JoinType.CrossApply ? JoinType.InnerJoin : JoinType.LeftJoin,
innerSelectExpression, transparentIdentifierType, joinPredicate);
return;
}
Expand Down Expand Up @@ -1122,8 +1122,8 @@ private void AddJoin(
JoinType.InnerJoin => new InnerJoinExpression(innerTable, joinPredicate),
JoinType.LeftJoin => new LeftJoinExpression(innerTable, joinPredicate),
JoinType.CrossJoin => new CrossJoinExpression(innerTable),
JoinType.InnerJoinLateral => new InnerJoinLateralExpression(innerTable),
JoinType.LeftJoinLateral => new LeftJoinLateralExpression(innerTable),
JoinType.CrossApply => new CrossApplyExpression(innerTable),
JoinType.OuterApply => new OuterApplyExpression(innerTable),
_ => throw new InvalidOperationException($"Invalid {nameof(joinType)}: {joinType}")
});

Expand All @@ -1139,7 +1139,7 @@ private void AddJoin(
}

var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
var innerNullable = joinType == JoinType.LeftJoin || joinType == JoinType.LeftJoinLateral;
var innerNullable = joinType == JoinType.LeftJoin || joinType == JoinType.OuterApply;
foreach (var projection in innerSelectExpression._projectionMapping)
{
var projectionToAdd = projection.Value;
Expand Down Expand Up @@ -1170,11 +1170,11 @@ public void AddLeftJoin(SelectExpression innerSelectExpression, SqlExpression jo
public void AddCrossJoin(SelectExpression innerSelectExpression, Type transparentIdentifierType)
=> AddJoin(JoinType.CrossJoin, innerSelectExpression, transparentIdentifierType);

public void AddInnerJoinLateral(SelectExpression innerSelectExpression, Type transparentIdentifierType)
=> AddJoin(JoinType.InnerJoinLateral, innerSelectExpression, transparentIdentifierType);
public void AddCrossApply(SelectExpression innerSelectExpression, Type transparentIdentifierType)
=> AddJoin(JoinType.CrossApply, innerSelectExpression, transparentIdentifierType);

public void AddLeftJoinLateral(SelectExpression innerSelectExpression, Type transparentIdentifierType)
=> AddJoin(JoinType.LeftJoinLateral, innerSelectExpression, transparentIdentifierType);
public void AddOuterApply(SelectExpression innerSelectExpression, Type transparentIdentifierType)
=> AddJoin(JoinType.OuterApply, innerSelectExpression, transparentIdentifierType);

private class SqlRemappingVisitor : ExpressionVisitor
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ protected override Expression VisitCrossJoin(CrossJoinExpression crossJoinExpres
return crossJoinExpression.Update(table);
}

protected override Expression VisitInnerJoinLateral(InnerJoinLateralExpression crossApplyExpression)
protected override Expression VisitCrossApply(CrossApplyExpression crossApplyExpression)
{
var parentSearchCondition = _isSearchCondition;
_isSearchCondition = false;
Expand All @@ -319,7 +319,7 @@ protected override Expression VisitInnerJoinLateral(InnerJoinLateralExpression c
return crossApplyExpression.Update(table);
}

protected override Expression VisitLeftJoinLateral(LeftJoinLateralExpression outerApplyExpression)
protected override Expression VisitOuterApply(OuterApplyExpression outerApplyExpression)
{
var parentSearchCondition = _isSearchCondition;
_isSearchCondition = false;
Expand Down
16 changes: 0 additions & 16 deletions src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,5 @@ protected override Expression VisitSqlFunction(SqlFunctionExpression sqlFunction

return base.VisitSqlFunction(sqlFunctionExpression);
}

protected override Expression VisitInnerJoinLateral(InnerJoinLateralExpression innerJoinLateralExpression)
{
Sql.Append("CROSS APPLY ");
Visit(innerJoinLateralExpression.Table);

return innerJoinLateralExpression;
}

protected override Expression VisitLeftJoinLateral(LeftJoinLateralExpression leftJoinLateralExpression)
{
Sql.Append("OUTER APPLY ");
Visit(leftJoinLateralExpression.Table);

return leftJoinLateralExpression;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public override async Task DateTimeOffset_Contains_Less_than_Greater_than(bool i
private string RemoveNewLines(string message)
=> message.Replace("\n", "").Replace("\r", "");

// Sqlite does not support lateral joins
// Sqlite does not support cross/outer apply
public override Task Correlated_collections_inner_subquery_predicate_references_outer_qsre(bool isAsync) => null;

public override Task Correlated_collections_inner_subquery_selector_references_outer_qsre(bool isAsync) => null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ LIMIT @__p_0
public override Task Project_single_element_from_collection_with_multiple_OrderBys_Take_and_FirstOrDefault_2(bool isAsync)
=> base.Project_single_element_from_collection_with_multiple_OrderBys_Take_and_FirstOrDefault_2(isAsync);

// Sqlite does not support lateral joins
// Sqlite does not support cross/outer apply
public override void Select_nested_collection_multi_level()
{
}
Expand Down

0 comments on commit 59ce5bf

Please sign in to comment.