Skip to content

Commit

Permalink
Remove quirks (#27357)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajcvickers authored Feb 4, 2022
1 parent 80bb7b3 commit 7b11078
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,48 +161,45 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
return Visit(ConvertObjectArrayEqualityComparison(binaryExpression.Left, binaryExpression.Right));
}

if (!(AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled))
{
if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual)
&& (binaryExpression.Left.IsNullConstantExpression() || binaryExpression.Right.IsNullConstantExpression()))
if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual)
&& (binaryExpression.Left.IsNullConstantExpression() || binaryExpression.Right.IsNullConstantExpression()))
{
var nonNullExpression = binaryExpression.Left.IsNullConstantExpression() ? binaryExpression.Right : binaryExpression.Left;
if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression
&& nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable)
&& nonNullMethodCallExpression.Method.IsGenericMethod
&& SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition()))
{
var nonNullExpression = binaryExpression.Left.IsNullConstantExpression() ? binaryExpression.Right : binaryExpression.Left;
if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression
&& nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable)
&& nonNullMethodCallExpression.Method.IsGenericMethod
&& SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition()))
var source = nonNullMethodCallExpression.Arguments[0];
if (nonNullMethodCallExpression.Arguments.Count == 2)
{
var source = nonNullMethodCallExpression.Arguments[0];
if (nonNullMethodCallExpression.Arguments.Count == 2)
{
source = Expression.Call(
QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()),
source,
nonNullMethodCallExpression.Arguments[1]);
}
source = Expression.Call(
QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()),
source,
nonNullMethodCallExpression.Arguments[1]);
}

var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source);
if (translatedSubquery != null)
var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source);
if (translatedSubquery != null)
{
var projection = translatedSubquery.ShaperExpression;
if (projection is NewExpression
|| RemoveConvert(projection) is EntityShaperExpression { IsNullable: false })
{
var projection = translatedSubquery.ShaperExpression;
if (projection is NewExpression
|| RemoveConvert(projection) is EntityShaperExpression { IsNullable: false })
{
var anySubquery = Expression.Call(
QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()),
translatedSubquery);

return Visit(
binaryExpression.NodeType == ExpressionType.Equal
? Expression.Not(anySubquery)
: anySubquery);
}

static Expression RemoveConvert(Expression e)
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
? RemoveConvert(unary.Operand)
: e;
var anySubquery = Expression.Call(
QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()),
translatedSubquery);

return Visit(
binaryExpression.NodeType == ExpressionType.Equal
? Expression.Not(anySubquery)
: anySubquery);
}

static Expression RemoveConvert(Expression e)
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
? RemoveConvert(unary.Operand)
: e;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,48 +302,45 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
right = rightOperand!;
}

if (!(AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled))
if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual)
&& (left.IsNullConstantExpression() || right.IsNullConstantExpression()))
{
if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual)
&& (left.IsNullConstantExpression() || right.IsNullConstantExpression()))
var nonNullExpression = left.IsNullConstantExpression() ? right : left;
if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression
&& nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable)
&& nonNullMethodCallExpression.Method.IsGenericMethod
&& SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition()))
{
var nonNullExpression = left.IsNullConstantExpression() ? right : left;
if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression
&& nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable)
&& nonNullMethodCallExpression.Method.IsGenericMethod
&& SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition()))
var source = nonNullMethodCallExpression.Arguments[0];
if (nonNullMethodCallExpression.Arguments.Count == 2)
{
var source = nonNullMethodCallExpression.Arguments[0];
if (nonNullMethodCallExpression.Arguments.Count == 2)
{
source = Expression.Call(
QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()),
source,
nonNullMethodCallExpression.Arguments[1]);
}
source = Expression.Call(
QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()),
source,
nonNullMethodCallExpression.Arguments[1]);
}

var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source);
if (translatedSubquery != null)
var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source);
if (translatedSubquery != null)
{
var projection = translatedSubquery.ShaperExpression;
if (projection is NewExpression
|| RemoveConvert(projection) is EntityShaperExpression { IsNullable: false })
{
var projection = translatedSubquery.ShaperExpression;
if (projection is NewExpression
|| RemoveConvert(projection) is EntityShaperExpression { IsNullable: false })
{
var anySubquery = Expression.Call(
QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()),
translatedSubquery);

return Visit(
binaryExpression.NodeType == ExpressionType.Equal
? Expression.Not(anySubquery)
: anySubquery);
}

static Expression RemoveConvert(Expression e)
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
? RemoveConvert(unary.Operand)
: e;
var anySubquery = Expression.Call(
QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()),
translatedSubquery);

return Visit(
binaryExpression.NodeType == ExpressionType.Equal
? Expression.Not(anySubquery)
: anySubquery);
}

static Expression RemoveConvert(Expression e)
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
? RemoveConvert(unary.Operand)
: e;
}
}
}
Expand Down
61 changes: 12 additions & 49 deletions src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2205,23 +2205,16 @@ private void AddJoin(
return;
}

if (!AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue27072", out var enabled27072) || !enabled27072)
if (originalInnerSelectPredicate != null)
{
if (originalInnerSelectPredicate != null)
if (innerSelectExpression.GroupBy.Count > 0)
{
if (innerSelectExpression.GroupBy.Count > 0)
{
innerSelectExpression.Having = originalInnerSelectPredicate;
}
else
{
innerSelectExpression.Predicate = originalInnerSelectPredicate;
}
innerSelectExpression.Having = originalInnerSelectPredicate;
}
else
{
innerSelectExpression.Predicate = originalInnerSelectPredicate;
}
}
else
{
innerSelectExpression.ApplyPredicate(joinPredicate);
}

joinPredicate = null;
Expand Down Expand Up @@ -2484,49 +2477,19 @@ static void GetPartitions(SelectExpression selectExpression, SqlExpression sqlEx

static bool IsContainedSql(SelectExpression selectExpression, SqlExpression sqlExpression)
{
if (!AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26756", out var enabled) || !enabled)
{
switch (sqlExpression)
{
case ColumnExpression columnExpression:
return selectExpression.ContainsTableReference(columnExpression);

case CaseExpression caseExpression
when caseExpression.ElseResult == null
&& caseExpression.Operand == null
&& caseExpression.WhenClauses.Count == 1
&& caseExpression.WhenClauses[0].Result is ColumnExpression resultColumn:
// We check condition in a separate function to avoid matching structure of condition outside of case block
return IsContainedCondition(selectExpression, caseExpression.WhenClauses[0].Test)
&& selectExpression.ContainsTableReference(resultColumn);

default:
return false;
}
}

switch (sqlExpression)
{
case ColumnExpression columnExpression:
return selectExpression.ContainsTableReference(columnExpression);

case SqlConstantExpression sqlConstantExpression
when sqlConstantExpression.Value == null:
return true;

case SqlBinaryExpression sqlBinaryExpression
when sqlBinaryExpression.OperatorType == ExpressionType.AndAlso
|| sqlBinaryExpression.OperatorType == ExpressionType.OrElse
|| sqlBinaryExpression.OperatorType == ExpressionType.NotEqual:
return IsContainedSql(selectExpression, sqlBinaryExpression.Left)
&& IsContainedSql(selectExpression, sqlBinaryExpression.Right);

case CaseExpression caseExpression
when caseExpression.ElseResult == null
&& caseExpression.Operand == null
&& caseExpression.WhenClauses.Count == 1:
return IsContainedSql(selectExpression, caseExpression.WhenClauses[0].Test)
&& IsContainedSql(selectExpression, caseExpression.WhenClauses[0].Result);
&& caseExpression.WhenClauses.Count == 1
&& caseExpression.WhenClauses[0].Result is ColumnExpression resultColumn:
// We check condition in a separate function to avoid matching structure of condition outside of case block
return IsContainedCondition(selectExpression, caseExpression.WhenClauses[0].Test)
&& selectExpression.ContainsTableReference(resultColumn);

default:
return false;
Expand Down
31 changes: 0 additions & 31 deletions src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,37 +71,6 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
}
}

if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled)
{
if (binaryExpression.NodeType == ExpressionType.Equal
|| binaryExpression.NodeType == ExpressionType.NotEqual)
{
var leftNullConstant = IsNullConstant(left);
var rightNullConstant = IsNullConstant(right);
if (leftNullConstant || rightNullConstant)
{
var nonNullExpression = leftNullConstant ? right : left;
if (nonNullExpression is MethodCallExpression methodCallExpression
&& methodCallExpression.Method.DeclaringType == typeof(Queryable)
&& methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() is MethodInfo genericMethod
&& SingleResultMethodInfos.Contains(genericMethod))
{
var result = Expression.Call(
(methodCallExpression.Arguments.Count == 2
? QueryableMethods.AnyWithPredicate
: QueryableMethods.AnyWithoutPredicate)
.MakeGenericMethod(methodCallExpression.Type),
methodCallExpression.Arguments);

return binaryExpression.NodeType == ExpressionType.Equal
? Expression.Not(result)
: result;
}
}
}
}

return binaryExpression.Update(left, binaryExpression.Conversion, right);
}

Expand Down

0 comments on commit 7b11078

Please sign in to comment.