diff --git a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs index 6d87975b472..845258dfb80 100644 --- a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs @@ -43,12 +43,14 @@ public interface ISqlExpressionFactory /// A to apply unary operator on. /// The type of the created expression. /// A type mapping to be assigned to the created expression. + /// An optional expression that can be re-used if it matches the new expression. /// A with the given arguments. SqlExpression? MakeUnary( ExpressionType operatorType, SqlExpression operand, Type type, - RelationalTypeMapping? typeMapping = null); + RelationalTypeMapping? typeMapping = null, + SqlExpression? existingExpr = null); /// /// Creates a new with the given arguments. @@ -275,11 +277,11 @@ SqlExpression Convert( /// Creates a new which represent a CASE statement in a SQL tree. /// /// An expression to compare with in . - /// A list of to compare and get result from. + /// A list of to compare or evaluate and get result from. /// A value to return if no matches, if any. /// An expression representing a CASE statement in a SQL tree. SqlExpression Case( - SqlExpression operand, + SqlExpression? operand, IReadOnlyList whenClauses, SqlExpression? elseResult); diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 8e3a5672aec..880e147ece7 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -599,10 +599,15 @@ public virtual SqlExpression Coalesce(SqlExpression left, SqlExpression right, R ExpressionType operatorType, SqlExpression operand, Type type, - RelationalTypeMapping? typeMapping = null) - => SqlUnaryExpression.IsValidOperator(operatorType) - ? ApplyTypeMapping(new SqlUnaryExpression(operatorType, operand, type, null), typeMapping) - : null; + RelationalTypeMapping? typeMapping = null, + SqlExpression? existingExpr = null) + => operatorType switch + { + ExpressionType.Not => ApplyTypeMapping(Not(operand, existingExpr), typeMapping), + _ when SqlUnaryExpression.IsValidOperator(operatorType) + => ApplyTypeMapping(new SqlUnaryExpression(operatorType, operand, type, null), typeMapping), + _ => null, + }; /// public virtual SqlExpression IsNull(SqlExpression operand) @@ -620,6 +625,66 @@ public virtual SqlExpression Convert(SqlExpression operand, Type type, Relationa public virtual SqlExpression Not(SqlExpression operand) => MakeUnary(ExpressionType.Not, operand, operand.Type, operand.TypeMapping)!; + private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpr) + => operand switch + { + // !(null) -> null + // ~(null) -> null (bitwise negation) + SqlConstantExpression { Value: null } => operand, + + // !(true) -> false + // !(false) -> true + SqlConstantExpression { Value: bool boolValue } => Constant(!boolValue, operand.Type, operand.TypeMapping), + + // !(!a) -> a + // ~(~a) -> a (bitwise negation) + SqlUnaryExpression { OperatorType: ExpressionType.Not } unary => unary.Operand, + + // !(a IS NULL) -> a IS NOT NULL + SqlUnaryExpression { OperatorType: ExpressionType.Equal } unary => IsNotNull(unary.Operand), + + // !(a IS NOT NULL) -> a IS NULL + SqlUnaryExpression { OperatorType: ExpressionType.NotEqual } unary => IsNull(unary.Operand), + + // !(a AND b) -> !a OR !b (De Morgan) + SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binary + => OrElse(Not(binary.Left), Not(binary.Right)), + + // !(a OR b) -> !a AND !b (De Morgan) + SqlBinaryExpression { OperatorType: ExpressionType.OrElse } binary + => AndAlso(Not(binary.Left), Not(binary.Right)), + + // use equality where possible + // !(a == true) -> a == false + // !(a == false) -> a == true + SqlBinaryExpression { OperatorType: ExpressionType.Equal, Right: SqlConstantExpression { Value: bool } } binary + => Equal(binary.Left, Not(binary.Right)), + + // !(true == a) -> false == a + // !(false == a) -> true == a + SqlBinaryExpression { OperatorType: ExpressionType.Equal, Left: SqlConstantExpression { Value: bool } } binary + => Equal(Not(binary.Left), binary.Right), + + // !(a == b) -> a != b + SqlBinaryExpression { OperatorType: ExpressionType.Equal } sqlBinaryOperand => NotEqual(sqlBinaryOperand.Left, sqlBinaryOperand.Right), + // !(a != b) -> a == b + SqlBinaryExpression { OperatorType: ExpressionType.NotEqual } sqlBinaryOperand => Equal(sqlBinaryOperand.Left, sqlBinaryOperand.Right), + + // !(CASE x WHEN t1 THEN r1 ... ELSE rN) -> CASE x WHEN t1 THEN !r1 ... ELSE !rN + CaseExpression caseExpression + when caseExpression.Type == typeof(bool) + && caseExpression.ElseResult is null or SqlConstantExpression + && caseExpression.WhenClauses.All(clause => clause.Result is SqlConstantExpression) + => Case( + caseExpression.Operand, + [.. caseExpression.WhenClauses.Select(clause => new CaseWhenClause(clause.Test, Not(clause.Result)))], + caseExpression.ElseResult is null ? null : Not(caseExpression.ElseResult)), + + _ => existingExpr is SqlUnaryExpression { OperatorType: ExpressionType.Not } unaryExpr && unaryExpr.Operand == operand + ? existingExpr + : new SqlUnaryExpression(ExpressionType.Not, operand, operand.Type, null), + }; + /// public virtual SqlExpression Negate(SqlExpression operand) => MakeUnary(ExpressionType.Negate, operand, operand.Type, operand.TypeMapping)!; @@ -627,18 +692,27 @@ public virtual SqlExpression Negate(SqlExpression operand) /// public virtual SqlExpression Case(SqlExpression? operand, IReadOnlyList whenClauses, SqlExpression? elseResult) { - var operandTypeMapping = operand!.TypeMapping - ?? whenClauses.Select(wc => wc.Test.TypeMapping).FirstOrDefault(t => t != null) - // Since we never look at type of Operand/Test after this place, - // we need to find actual typeMapping based on non-object type. - ?? new[] { operand.Type }.Concat(whenClauses.Select(wc => wc.Test.Type)) - .Where(t => t != typeof(object)).Select(t => _typeMappingSource.FindMapping(t, Dependencies.Model)) - .FirstOrDefault(); + RelationalTypeMapping? testTypeMapping; + if (operand == null) + { + testTypeMapping = _boolTypeMapping; + } + else + { + testTypeMapping = operand.TypeMapping + ?? whenClauses.Select(wc => wc.Test.TypeMapping).FirstOrDefault(t => t != null) + // Since we never look at type of Operand/Test after this place, + // we need to find actual typeMapping based on non-object type. + ?? new[] { operand.Type }.Concat(whenClauses.Select(wc => wc.Test.Type)) + .Where(t => t != typeof(object)).Select(t => _typeMappingSource.FindMapping(t, Dependencies.Model)) + .FirstOrDefault(); + + operand = ApplyTypeMapping(operand, testTypeMapping); + } var resultTypeMapping = elseResult?.TypeMapping ?? whenClauses.Select(wc => wc.Result.TypeMapping).FirstOrDefault(t => t != null); - operand = ApplyTypeMapping(operand, operandTypeMapping); elseResult = ApplyTypeMapping(elseResult, resultTypeMapping); var typeMappedWhenClauses = new List(); @@ -646,7 +720,7 @@ public virtual SqlExpression Case(SqlExpression? operand, IReadOnlyList public virtual SqlExpression Case(IReadOnlyList whenClauses, SqlExpression? elseResult) - { - var resultTypeMapping = elseResult?.TypeMapping - ?? whenClauses.Select(wc => wc.Result.TypeMapping).FirstOrDefault(t => t != null); - - var typeMappedWhenClauses = new List(); - foreach (var caseWhenClause in whenClauses) - { - typeMappedWhenClauses.Add( - new CaseWhenClause( - ApplyTypeMapping(caseWhenClause.Test, _boolTypeMapping), - ApplyTypeMapping(caseWhenClause.Result, resultTypeMapping))); - } - - elseResult = ApplyTypeMapping(elseResult, resultTypeMapping); - - return new CaseExpression(typeMappedWhenClauses, elseResult); - } + => Case(operand: null, whenClauses, elseResult); /// public virtual SqlExpression Function( diff --git a/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs index 6693ca918ae..ee52be5c94a 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs @@ -24,10 +24,10 @@ public class CaseExpression : SqlExpression /// Creates a new instance of the class which represents a simple CASE expression. /// /// An expression to compare with in . - /// A list of to compare and get result from. + /// A list of to compare or evaluate and get result from. /// A value to return if no matches, if any. public CaseExpression( - SqlExpression operand, + SqlExpression? operand, IReadOnlyList whenClauses, SqlExpression? elseResult = null) : base(whenClauses[0].Result.Type, whenClauses[0].Result.TypeMapping) @@ -45,10 +45,8 @@ public CaseExpression( public CaseExpression( IReadOnlyList whenClauses, SqlExpression? elseResult = null) - : base(whenClauses[0].Result.Type, whenClauses[0].Result.TypeMapping) + : this(null, whenClauses, elseResult) { - _whenClauses.AddRange(whenClauses); - ElseResult = elseResult; } /// @@ -94,9 +92,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) changed |= elseResult != ElseResult; return changed - ? operand == null - ? new CaseExpression(whenClauses, elseResult) - : new CaseExpression(operand, whenClauses, elseResult) + ? new CaseExpression(operand, whenClauses, elseResult) : this; } @@ -113,9 +109,7 @@ public virtual CaseExpression Update( IReadOnlyList whenClauses, SqlExpression? elseResult) => operand != Operand || !whenClauses.SequenceEqual(WhenClauses) || elseResult != ElseResult - ? (operand == null - ? new CaseExpression(whenClauses, elseResult) - : new CaseExpression(operand, whenClauses, elseResult)) + ? new CaseExpression(operand, whenClauses, elseResult) : this; /// diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index a2eb5fc3206..20f898cb8ab 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -1067,10 +1067,9 @@ protected virtual SqlExpression VisitLike(LikeExpression likeExpression, bool al return result; SqlExpression GenerateNotNullCheck(SqlExpression operand) - => OptimizeNonNullableNotExpression( - _sqlExpressionFactory.Not( - ProcessNullNotNull( - _sqlExpressionFactory.IsNull(operand), operandNullable: true))); + => _sqlExpressionFactory.Not( + ProcessNullNotNull( + _sqlExpressionFactory.IsNull(operand), operandNullable: true)); } /// @@ -1543,9 +1542,7 @@ protected virtual SqlExpression VisitSqlUnary( nullable = operandNullable; - return !operandNullable && sqlUnaryExpression.OperatorType == ExpressionType.Not - ? OptimizeNonNullableNotExpression(updated) - : updated; + return OptimizeNotExpression(updated); } /// @@ -1695,7 +1692,7 @@ private SqlExpression OptimizeComparison( // a != true -> !a // a != false -> a return sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ rightBoolValue - ? OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(left)) + ? OptimizeNotExpression(_sqlExpressionFactory.Not(left)) : left; } @@ -1711,7 +1708,7 @@ private SqlExpression OptimizeComparison( // true != a -> !a // false != a -> a return sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftBoolValue - ? OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(right)) + ? OptimizeNotExpression(_sqlExpressionFactory.Not(right)) : right; } @@ -1791,10 +1788,10 @@ private SqlExpression RewriteNullSemantics( } var leftIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(left), leftNullable); - var leftIsNotNull = OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(leftIsNull)); + var leftIsNotNull = _sqlExpressionFactory.Not(leftIsNull); var rightIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(right), rightNullable); - var rightIsNotNull = OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(rightIsNull)); + var rightIsNotNull = _sqlExpressionFactory.Not(rightIsNull); SqlExpression body; if (leftNegated == rightNegated) @@ -1825,152 +1822,51 @@ private SqlExpression RewriteNullSemantics( if (sqlBinaryExpression.OperatorType == ExpressionType.NotEqual) { - // simplify using DeMorgan - body = OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(body)); + // the factory takes care of simplifying using DeMorgan + body = _sqlExpressionFactory.Not(body); } return body; } /// - /// Attempts to simplify a unary not operation on a non-nullable operand. + /// Attempts to simplify a unary not operation. /// /// The expression to simplify. /// The simplified expression, or the original expression if it cannot be simplified. - protected virtual SqlExpression OptimizeNonNullableNotExpression(SqlExpression expression) + protected virtual SqlExpression OptimizeNotExpression(SqlExpression expression) { - if (expression is not SqlUnaryExpression sqlUnaryExpression - || sqlUnaryExpression.OperatorType != ExpressionType.Not) + if (expression is not SqlUnaryExpression { OperatorType: ExpressionType.Not } sqlUnaryExpression) { return expression; } - switch (sqlUnaryExpression.Operand) + // !(a > b) -> a <= b + // !(a >= b) -> a < b + // !(a < b) -> a >= b + // !(a <= b) -> a > b + if (sqlUnaryExpression.Operand is SqlBinaryExpression sqlBinaryOperand + && TryNegate(sqlBinaryOperand.OperatorType, out var negated)) { - // !(true) -> false - // !(false) -> true - case SqlConstantExpression { Value: bool value }: - { - return _sqlExpressionFactory.Constant(!value, sqlUnaryExpression.TypeMapping); - } - - case SqlUnaryExpression sqlUnaryOperand: - { - switch (sqlUnaryOperand.OperatorType) - { - // !(!a) -> a - case ExpressionType.Not: - return sqlUnaryOperand.Operand; - - //!(a IS NULL) -> a IS NOT NULL - case ExpressionType.Equal: - return _sqlExpressionFactory.IsNotNull(sqlUnaryOperand.Operand); - - //!(a IS NOT NULL) -> a IS NULL - case ExpressionType.NotEqual: - return _sqlExpressionFactory.IsNull(sqlUnaryOperand.Operand); - } - - break; - } - - case SqlBinaryExpression sqlBinaryOperand: - { - // optimizations below are only correct in 2-value logic - // De Morgan's - if (sqlBinaryOperand.OperatorType is ExpressionType.AndAlso or ExpressionType.OrElse) - { - // since entire AndAlso/OrElse expression is non-nullable, both sides of it (left and right) must also be non-nullable - // so it's safe to perform recursive optimization here - var left = OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(sqlBinaryOperand.Left)); - var right = OptimizeNonNullableNotExpression(_sqlExpressionFactory.Not(sqlBinaryOperand.Right)); - - return _sqlExpressionFactory.MakeBinary( - sqlBinaryOperand.OperatorType == ExpressionType.AndAlso - ? ExpressionType.OrElse - : ExpressionType.AndAlso, - left, - right, - sqlBinaryOperand.TypeMapping)!; - } - - // use equality where possible - // !(a == true) -> a == false - // !(a == false) -> a == true - // !(true == a) -> false == a - // !(false == a) -> true == a - if (sqlBinaryOperand.OperatorType == ExpressionType.Equal) - { - if (sqlBinaryOperand.Left is SqlConstantExpression leftConstant - && leftConstant.Type == typeof(bool)) - { - return _sqlExpressionFactory.MakeBinary( - ExpressionType.Equal, - _sqlExpressionFactory.Constant(!(bool)leftConstant.Value!, leftConstant.TypeMapping), - sqlBinaryOperand.Right, - sqlBinaryOperand.TypeMapping)!; - } - - if (sqlBinaryOperand.Right is SqlConstantExpression rightConstant - && rightConstant.Type == typeof(bool)) - { - return _sqlExpressionFactory.MakeBinary( - ExpressionType.Equal, - sqlBinaryOperand.Left, - _sqlExpressionFactory.Constant(!(bool)rightConstant.Value!, rightConstant.TypeMapping), - sqlBinaryOperand.TypeMapping)!; - } - } - - // !(a == b) -> a != b - // !(a != b) -> a == b - // !(a > b) -> a <= b - // !(a >= b) -> a < b - // !(a < b) -> a >= b - // !(a <= b) -> a > b - if (TryNegate(sqlBinaryOperand.OperatorType, out var negated)) - { - return _sqlExpressionFactory.MakeBinary( - negated, - sqlBinaryOperand.Left, - sqlBinaryOperand.Right, - sqlBinaryOperand.TypeMapping)!; - } - } - break; - - case CaseExpression caseExpression: - { - if (caseExpression.Type == typeof(bool) - && caseExpression.ElseResult is SqlConstantExpression elseResult - && caseExpression.WhenClauses.All(clause => clause.Result is SqlConstantExpression) - ) - { - var clauses = caseExpression.WhenClauses - .Select(clause => new CaseWhenClause( - clause.Test, - _sqlExpressionFactory.Constant(!(bool)(clause.Result as SqlConstantExpression)!.Value!, clause.Result.TypeMapping)) - ) - .ToList(); - var newElseResult = _sqlExpressionFactory.Constant(!(bool)elseResult.Value!, elseResult.TypeMapping); - - return caseExpression.Operand is null - ? _sqlExpressionFactory.Case(clauses, newElseResult) - : _sqlExpressionFactory.Case(caseExpression.Operand, clauses, newElseResult); - } - } - - break; + return _sqlExpressionFactory.MakeBinary( + negated, + sqlBinaryOperand.Left, + sqlBinaryOperand.Right, + sqlBinaryOperand.TypeMapping)!; } - return sqlUnaryExpression; + // the factory can optimize most `NOT` expressions + return _sqlExpressionFactory.MakeUnary( + sqlUnaryExpression.OperatorType, + sqlUnaryExpression.Operand, + sqlUnaryExpression.Type, + sqlUnaryExpression.TypeMapping, + sqlUnaryExpression)!; static bool TryNegate(ExpressionType expressionType, out ExpressionType result) { var negated = expressionType switch { - ExpressionType.Equal => ExpressionType.NotEqual, - ExpressionType.NotEqual => ExpressionType.Equal, ExpressionType.GreaterThan => ExpressionType.LessThanOrEqual, ExpressionType.GreaterThanOrEqual => ExpressionType.LessThan, ExpressionType.LessThan => ExpressionType.GreaterThanOrEqual, diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs index 23a599baeda..b757fd90033 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs @@ -1172,11 +1172,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Level1_Required_Id] = [l].[Id] * 2 OR CAST(LEN([l2].[Level2_Name]) AS int) = CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END OR ([l2].[Level2_Name] IS NULL AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL)) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Level1_Required_Id] = [l].[Id] * 2 OR CAST(LEN([l2].[Level2_Name]) AS int) = [l2].[Id] OR ([l2].[Level2_Name] IS NULL AND [l2].[Id] IS NULL)) ) AS [s] LEFT JOIN ( SELECT [l3].[Id], [l3].[OneToOne_Required_PK_Date], [l3].[Level1_Optional_Id], [l3].[Level1_Required_Id], [l3].[Level2_Name], [l3].[OneToMany_Optional_Inverse2Id], [l3].[OneToMany_Required_Inverse2Id], [l3].[OneToOne_Optional_PK_Inverse2Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index 45d923f908e..9a04d360e86 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -2487,12 +2487,15 @@ public override async Task GroupJoin_with_subquery_on_inner(bool async) """ SELECT [l].[Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(10) 1 AS empty - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[Level1_Optional_Id] AND [l0].[Id] > 0 - ORDER BY [l0].[Id] -) AS [l1] +LEFT JOIN ( + SELECT [l1].[Level1_Optional_Id] + FROM ( + SELECT [l0].[Level1_Optional_Id], ROW_NUMBER() OVER(PARTITION BY [l0].[Level1_Optional_Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE [l0].[Id] > 0 + ) AS [l1] + WHERE [l1].[row] <= 10 +) AS [l2] ON [l].[Id] = [l2].[Level1_Optional_Id] """); } @@ -2504,12 +2507,15 @@ public override async Task GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpt """ SELECT [l].[Id] FROM [LevelOne] AS [l] -CROSS APPLY ( - SELECT TOP(10) 1 AS empty - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[Level1_Optional_Id] AND [l0].[Id] > 0 - ORDER BY [l0].[Id] -) AS [l1] +INNER JOIN ( + SELECT [l1].[Level1_Optional_Id] + FROM ( + SELECT [l0].[Level1_Optional_Id], ROW_NUMBER() OVER(PARTITION BY [l0].[Level1_Optional_Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE [l0].[Id] > 0 + ) AS [l1] + WHERE [l1].[row] <= 10 +) AS [l2] ON [l].[Id] = [l2].[Level1_Optional_Id] """); } @@ -3536,7 +3542,7 @@ SELECT CASE WHEN NOT EXISTS ( SELECT 1 FROM [LevelOne] AS [l] - WHERE [l].[Name] = N'Foo' AND [l].[Name] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [l].[Name] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs index fb0cc9ffd47..c07c15b88a0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs @@ -627,14 +627,13 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] END = CASE WHEN [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l4].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL AND EXISTS ( - SELECT 1 - FROM [Level1] AS [l5] - WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l].[Id] = [l5].[OneToMany_Required_Inverse2Id] AND (CASE - WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] - END = [l4].[Level2_Required_Id] OR (CASE + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL AND [l4].[Level2_Required_Id] IN ( + SELECT CASE WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] - END IS NULL AND [l4].[Level2_Required_Id] IS NULL))) + END + FROM [Level1] AS [l5] + WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l].[Id] = [l5].[OneToMany_Required_Inverse2Id] + ) ) AS [s] LEFT JOIN ( SELECT [l6].[Id], [l6].[OneToOne_Required_PK_Date], [l6].[Level1_Optional_Id], [l6].[Level1_Required_Id], [l6].[Level2_Name], [l6].[OneToMany_Optional_Inverse2Id], [l6].[OneToMany_Required_Inverse2Id], [l6].[OneToOne_Optional_PK_Inverse2Id] @@ -1616,9 +1615,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] ) AS [l1] ON [l].[Id] = CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] END - WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] - END < 5 + WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l1].[Id] < 5 ) AS [s] ON 1 = 1 CROSS APPLY ( SELECT [l2].[Id], [l2].[Date], [l2].[Name] @@ -1792,9 +1789,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END < 10 + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] < 10 ) AS [s] """); } @@ -2217,9 +2212,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] ) AS [l1] ON [l].[Id] = CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] END -WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] -END = 7 +WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l1].[Id] = 7 """); } @@ -2285,9 +2278,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] ) AS [l1] ON [l].[Id] = CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] END -WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] -END = 7 AND (( +WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l1].[Id] = 7 AND (( SELECT TOP(1) [l5].[Name] FROM [Level1] AS [l2] LEFT JOIN ( @@ -2535,9 +2526,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] ) AS [l1] ON [l].[Id] = CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] END -WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] -END = 7 +WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l1].[Id] = 7 """); } @@ -2665,9 +2654,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END > 2 + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] > 2 ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] """); } @@ -5278,13 +5265,7 @@ WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND EXISTS ( SELECT 1 FROM [Level1] AS [l2] - WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] - END IS NOT NULL AND (CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] - END = [l2].[OneToMany_Optional_Inverse3Id] OR (CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] - END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) + WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL AND [l1].[Id] IS NOT NULL AND [l1].[Id] = [l2].[OneToMany_Optional_Inverse3Id]) """); } @@ -7044,7 +7025,7 @@ SELECT CASE WHEN NOT EXISTS ( SELECT 1 FROM [Level1] AS [l] - WHERE [l].[Name] = N'Foo' AND [l].[Name] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [l].[Name] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -7799,23 +7780,24 @@ public override async Task GroupJoin_with_subquery_on_inner(bool async) """ SELECT [l].[Id] FROM [Level1] AS [l] -OUTER APPLY ( - SELECT TOP(10) 1 AS empty - FROM [Level1] AS [l0] - LEFT JOIN ( - SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] - FROM [Level1] AS [l1] - WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL - ) AS [l2] ON [l0].[Id] = CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l].[Id] = [l2].[Level1_Optional_Id] AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END > 0 - ORDER BY CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END -) AS [s] +LEFT JOIN ( + SELECT [s].[Level1_Optional_Id] + FROM ( + SELECT [l2].[Level1_Optional_Id], ROW_NUMBER() OVER(PARTITION BY [l2].[Level1_Optional_Id] ORDER BY CASE + WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] + END) AS [row] + FROM [Level1] AS [l0] + LEFT JOIN ( + SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] + FROM [Level1] AS [l1] + WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL + ) AS [l2] ON [l0].[Id] = CASE + WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] + END + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] > 0 + ) AS [s] + WHERE [s].[row] <= 10 +) AS [s0] ON [l].[Id] = [s0].[Level1_Optional_Id] """); } @@ -7827,23 +7809,24 @@ public override async Task GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpt """ SELECT [l].[Id] FROM [Level1] AS [l] -CROSS APPLY ( - SELECT TOP(10) 1 AS empty - FROM [Level1] AS [l0] - LEFT JOIN ( - SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] - FROM [Level1] AS [l1] - WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL - ) AS [l2] ON [l0].[Id] = CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l].[Id] = [l2].[Level1_Optional_Id] AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END > 0 - ORDER BY CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END -) AS [s] +INNER JOIN ( + SELECT [s].[Level1_Optional_Id] + FROM ( + SELECT [l2].[Level1_Optional_Id], ROW_NUMBER() OVER(PARTITION BY [l2].[Level1_Optional_Id] ORDER BY CASE + WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] + END) AS [row] + FROM [Level1] AS [l0] + LEFT JOIN ( + SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] + FROM [Level1] AS [l1] + WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL + ) AS [l2] ON [l0].[Id] = CASE + WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] + END + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] > 0 + ) AS [s] + WHERE [s].[row] <= 10 +) AS [s0] ON [l].[Id] = [s0].[Level1_Optional_Id] """); } @@ -8063,11 +8046,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] """); } @@ -8094,11 +8073,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] """); } @@ -8128,11 +8103,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm1_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm1_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] LEFT JOIN ( SELECT [l7].[Id] AS [Id1], [l7].[Level2_Optional_Id], [l7].[Level2_Required_Id], [l7].[OneToMany_Required_Inverse3Id] @@ -8153,11 +8124,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] END = CASE WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] END - WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND (CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END <> @__prm2_1 OR CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END IS NULL) + WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l7].[Id] <> @__prm2_1 OR [l7].[Id] IS NULL) ) AS [s0] ON CASE WHEN [s].[OneToOne_Required_PK_Date] IS NOT NULL AND [s].[Level1_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [s].[Id0] END = [s0].[Level2_Optional_Id] @@ -8189,11 +8156,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm1_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm1_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] INNER JOIN ( SELECT [l7].[Id] AS [Id1], [l7].[Level2_Optional_Id], [l7].[Level2_Required_Id], [l7].[OneToMany_Required_Inverse3Id] @@ -8214,11 +8177,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] END = CASE WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] END - WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND (CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END <> @__prm2_1 OR CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END IS NULL) + WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l7].[Id] <> @__prm2_1 OR [l7].[Id] IS NULL) ) AS [s0] ON CASE WHEN [s].[OneToOne_Required_PK_Date] IS NOT NULL AND [s].[Level1_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [s].[Id0] END = [s0].[Level2_Optional_Id] @@ -8249,11 +8208,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] LEFT JOIN ( SELECT [l7].[Id] AS [Id1], [l7].[Level2_Optional_Id], [l7].[Level2_Required_Id], [l7].[OneToMany_Required_Inverse3Id] @@ -8274,11 +8229,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] END = CASE WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] END - WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND (CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END <> @__prm_0 OR CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END IS NULL) + WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l7].[Id] <> @__prm_0 OR [l7].[Id] IS NULL) ) AS [s0] ON CASE WHEN [s].[OneToOne_Required_PK_Date] IS NOT NULL AND [s].[Level1_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [s].[Id0] END = [s0].[Level2_Optional_Id] @@ -8309,11 +8260,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] ) AS [l2] ON [l0].[Id] = CASE WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END - WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND (CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END <> @__prm_0 OR CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] - END IS NULL) + WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] <> @__prm_0 OR [l2].[Id] IS NULL) ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] INNER JOIN ( SELECT [l7].[Id] AS [Id1], [l7].[Level2_Optional_Id], [l7].[Level2_Required_Id], [l7].[OneToMany_Required_Inverse3Id] @@ -8334,11 +8281,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] END = CASE WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] END - WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND (CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END <> @__prm_0 OR CASE - WHEN [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l7].[Id] - END IS NULL) + WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l7].[Level2_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l7].[Id] <> @__prm_0 OR [l7].[Id] IS NULL) ) AS [s0] ON CASE WHEN [s].[OneToOne_Required_PK_Date] IS NOT NULL AND [s].[Level1_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [s].[Id0] END = [s0].[Level2_Optional_Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Ef6GroupBySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Ef6GroupBySqlServerTest.cs index 69c15196f88..018d20fb4b7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/Ef6GroupBySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Ef6GroupBySqlServerTest.cs @@ -483,12 +483,11 @@ public override async Task Group_Join_from_LINQ_101(bool async) """ SELECT [c].[Id], [c].[CompanyName], [c].[Region], [s].[Id], [s].[CustomerId], [s].[OrderDate], [s].[Total], [s].[Id0] FROM [CustomerForLinq] AS [c] -OUTER APPLY ( +LEFT JOIN ( SELECT [o].[Id], [o].[CustomerId], [o].[OrderDate], [o].[Total], [c0].[Id] AS [Id0] FROM [OrderForLinq] AS [o] LEFT JOIN [CustomerForLinq] AS [c0] ON [o].[CustomerId] = [c0].[Id] - WHERE [c].[Id] = [c0].[Id] -) AS [s] +) AS [s] ON [c].[Id] = [s].[Id0] ORDER BY [c].[Id], [s].[Id] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 69486ff10ed..77fd634944c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -3089,7 +3089,7 @@ WHEN NOT EXISTS ( SELECT 1 FROM [Gears] AS [g] LEFT JOIN [Tags] AS [t] ON [g].[Nickname] = [t].[GearNickName] AND [g].[SquadId] = [t].[GearSquadId] - WHERE [t].[Note] = N'Foo' AND [t].[Note] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [t].[Note] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs index a060e8d211a..48c3758e51a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs @@ -310,13 +310,9 @@ public override async Task GroupJoin_as_final_operator(bool 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], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] +SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Customers] AS [c] -OUTER APPLY ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] -) AS [o0] +LEFT JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID] WHERE [c].[CustomerID] LIKE N'F%' ORDER BY [c].[CustomerID] """); @@ -328,13 +324,9 @@ public override async Task Unflattened_GroupJoin_composed(bool 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], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] +SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Customers] AS [c] -OUTER APPLY ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] -) AS [o0] +LEFT JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID] WHERE [c].[CustomerID] LIKE N'F%' AND [c].[City] = N'Lisboa' ORDER BY [c].[CustomerID] """); @@ -346,18 +338,14 @@ public override async Task Unflattened_GroupJoin_composed_2(bool 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], [c1].[CustomerID], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate], [c1].[Address], [c1].[City], [c1].[CompanyName], [c1].[ContactName], [c1].[ContactTitle], [c1].[Country], [c1].[Fax], [c1].[Phone], [c1].[PostalCode], [c1].[Region] +SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [c1].[CustomerID], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [c1].[Address], [c1].[City], [c1].[CompanyName], [c1].[ContactName], [c1].[ContactTitle], [c1].[Country], [c1].[Fax], [c1].[Phone], [c1].[PostalCode], [c1].[Region] FROM [Customers] AS [c] INNER JOIN ( SELECT [c0].[CustomerID], [c0].[Address], [c0].[City], [c0].[CompanyName], [c0].[ContactName], [c0].[ContactTitle], [c0].[Country], [c0].[Fax], [c0].[Phone], [c0].[PostalCode], [c0].[Region] FROM [Customers] AS [c0] WHERE [c0].[City] = N'Lisboa' ) AS [c1] ON [c].[CustomerID] = [c1].[CustomerID] -OUTER APPLY ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] -) AS [o0] +LEFT JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID] WHERE [c].[CustomerID] LIKE N'F%' ORDER BY [c].[CustomerID], [c1].[CustomerID] """); @@ -515,11 +503,11 @@ public override async Task GroupJoin_SelectMany_subquery_with_filter_orderby(boo """ SELECT [c].[ContactName], [o0].[OrderID] FROM [Customers] AS [c] -CROSS APPLY ( - SELECT [o].[OrderID] +INNER JOIN ( + SELECT [o].[OrderID], [o].[CustomerID] FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] AND [o].[OrderID] > 5 -) AS [o0] + WHERE [o].[OrderID] > 5 +) AS [o0] ON [c].[CustomerID] = [o0].[CustomerID] """); } @@ -548,11 +536,11 @@ public override async Task GroupJoin_SelectMany_subquery_with_filter_orderby_and """ SELECT [c].[ContactName], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] FROM [Customers] AS [c] -OUTER APPLY ( +LEFT JOIN ( SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] AND [o].[OrderID] > 5 -) AS [o0] + WHERE [o].[OrderID] > 5 +) AS [o0] ON [c].[CustomerID] = [o0].[CustomerID] WHERE [c].[CustomerID] LIKE N'F%' """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs index 66f69d3fb5b..4929764ce71 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs @@ -214,7 +214,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableIntA] = [e].[IntB] AND [e].[NullableIntA] IS NOT NULL +WHERE [e].[NullableIntA] = [e].[IntB] """, // """ @@ -228,7 +228,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL +WHERE [e].[IntA] = [e].[NullableIntB] """, // """ @@ -242,7 +242,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableIntA] = [e].[NullableIntB] AND [e].[NullableIntA] IS NOT NULL AND [e].[NullableIntB] IS NOT NULL) OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +WHERE [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) """); } @@ -948,7 +948,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] = [e].[NullableBoolB] """, // """ @@ -976,7 +976,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] <> [e].[NullableBoolB] """, // """ @@ -990,7 +990,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] = [e].[BoolB] """, // """ @@ -1004,7 +1004,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] = [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """, // """ @@ -1018,7 +1018,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] <> [e].[BoolB] """, // """ @@ -1032,7 +1032,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """, // """ @@ -1060,7 +1060,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] <> [e].[NullableBoolB] """, // """ @@ -1088,7 +1088,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] = [e].[NullableBoolB] """, // """ @@ -1102,7 +1102,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] <> [e].[BoolB] """, // """ @@ -1116,7 +1116,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """, // """ @@ -1130,7 +1130,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] = [e].[BoolB] """, // """ @@ -1144,7 +1144,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] = [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """); } @@ -1522,19 +1522,19 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] = [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] = [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """); } @@ -1552,19 +1552,19 @@ WHERE [e].[BoolA] <> [e].[BoolB] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] <> [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] <> [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """); } @@ -1582,19 +1582,19 @@ WHERE [e].[BoolA] <> [e].[BoolB] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] <> [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] <> [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """); } @@ -1612,19 +1612,19 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL +WHERE [e].[BoolA] = [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL +WHERE [e].[NullableBoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] = [e].[NullableBoolB] AND [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """); } @@ -4387,7 +4387,7 @@ public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullab """ SELECT [e].[Id], [e].[BoolA], [e].[BoolB], [e].[BoolC], [e].[IntA], [e].[IntB], [e].[IntC], [e].[NullableBoolA], [e].[NullableBoolB], [e].[NullableBoolC], [e].[NullableIntA], [e].[NullableIntB], [e].[NullableIntC], [e].[NullableStringA], [e].[NullableStringB], [e].[NullableStringC], [e].[StringA], [e].[StringB], [e].[StringC] FROM [Entities1] AS [e] -WHERE [e].[NullableStringA] IS NOT NULL OR ([e].[NullableStringA] = N'Foo' AND [e].[NullableStringA] IS NOT NULL) +WHERE [e].[NullableStringA] IS NOT NULL OR [e].[NullableStringA] = N'Foo' """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 3a8a0a59225..533c570af09 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -4154,7 +4154,7 @@ UNION ALL FROM [Officers] AS [o] ) AS [u] LEFT JOIN [Tags] AS [t] ON [u].[Nickname] = [t].[GearNickName] AND [u].[SquadId] = [t].[GearSquadId] - WHERE [t].[Note] = N'Foo' AND [t].[Note] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [t].[Note] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 2d7a70d058e..e5eb5ca84f1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -3523,7 +3523,7 @@ WHEN NOT EXISTS ( SELECT 1 FROM [Gears] AS [g] LEFT JOIN [Tags] AS [t] ON [g].[Nickname] = [t].[GearNickName] AND [g].[SquadId] = [t].[GearSquadId] - WHERE [t].[Note] = N'Foo' AND [t].[Note] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [t].[Note] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs index 9e442c6a1dc..f772b926c0f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalComplexNavigationsCollectionsSharedTypeQuerySqlServerTest.cs @@ -1866,9 +1866,9 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[PeriodEnd] IS NOT NULL AND [l2].[PeriodStart] IS NOT NULL THEN [l2].[PeriodEnd] + WHEN [l2].[PeriodEnd] IS NOT NULL AND [l2].[PeriodStart] IS NOT NULL THEN [l2].[PeriodEnd] END IS NOT NULL AND CASE - WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[PeriodEnd] IS NOT NULL AND [l2].[PeriodStart] IS NOT NULL THEN [l2].[PeriodStart] + WHEN [l2].[PeriodEnd] IS NOT NULL AND [l2].[PeriodStart] IS NOT NULL THEN [l2].[PeriodStart] END IS NOT NULL ) AS [s] ON [l].[Id] = [s].[Level1_Required_Id] LEFT JOIN ( @@ -2801,11 +2801,7 @@ LEFT JOIN ( FROM [Level1] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l2] WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL ) AS [l3] ON [l].[Id] = [l3].[OneToMany_Optional_Inverse2Id] -WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[PeriodEnd] -END IS NOT NULL AND CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[PeriodStart] -END IS NOT NULL +WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL ORDER BY [l].[Id], [l1].[Id] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index 9f5edb44b77..3f18a794b31 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -614,7 +614,7 @@ WHEN NOT EXISTS ( SELECT 1 FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] LEFT JOIN [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] ON [g].[Nickname] = [t].[GearNickName] AND [g].[SquadId] = [t].[GearSquadId] - WHERE [t].[Note] = N'Foo' AND [t].[Note] IS NOT NULL) THEN CAST(1 AS bit) + WHERE [t].[Note] = N'Foo') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs index 6d1eb1e27ac..5b2879e3b16 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs @@ -40,18 +40,6 @@ public override Task GroupJoin_client_method_in_OrderBy(bool async) "Microsoft.EntityFrameworkCore.Query.ComplexNavigationsQueryTestBase", "ClientMethodNullableInt")); - public override async Task GroupJoin_with_subquery_on_inner(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_with_subquery_on_inner(async))).Message); - - public override async Task GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpty(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpty(async))).Message); - public override async Task Correlated_projection_with_first(bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqliteTest.cs index afc6ec374df..b596d381a4e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqliteTest.cs @@ -41,18 +41,6 @@ public override async Task Prune_does_not_throw_null_ref(bool async) (await Assert.ThrowsAsync( () => base.Prune_does_not_throw_null_ref(async))).Message); - public override async Task GroupJoin_with_subquery_on_inner(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_with_subquery_on_inner(async))).Message); - - public override async Task GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpty(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_with_subquery_on_inner_and_no_DefaultIfEmpty(async))).Message); - public override async Task Correlated_projection_with_first(bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Ef6GroupBySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Ef6GroupBySqliteTest.cs index 01aab7d8271..cda96d9fcd8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/Ef6GroupBySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Ef6GroupBySqliteTest.cs @@ -49,12 +49,6 @@ public override async Task Whats_new_2021_sample_5(bool async) public override async Task Whats_new_2021_sample_6(bool async) => await base.Whats_new_2021_sample_6(async); - public override async Task Group_Join_from_LINQ_101(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.Group_Join_from_LINQ_101(async))).Message); - private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 085a4ff7665..e6bb1577742 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -8953,7 +8953,7 @@ SELECT NOT EXISTS ( SELECT 1 FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" - WHERE "t"."Note" = 'Foo' AND "t"."Note" IS NOT NULL) + WHERE "t"."Note" = 'Foo') """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs index f552fd9298d..7051721f131 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs @@ -57,34 +57,4 @@ public override async Task Take_in_collection_projection_with_FirstOrDefault_on_ SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Take_in_collection_projection_with_FirstOrDefault_on_top_level(async))).Message); - - public override async Task GroupJoin_as_final_operator(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_as_final_operator(async))).Message); - - public override async Task Unflattened_GroupJoin_composed(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.Unflattened_GroupJoin_composed(async))).Message); - - public override async Task Unflattened_GroupJoin_composed_2(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.Unflattened_GroupJoin_composed_2(async))).Message); - - public override async Task GroupJoin_SelectMany_subquery_with_filter_orderby(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_SelectMany_subquery_with_filter_orderby(async))).Message); - - public override async Task GroupJoin_SelectMany_subquery_with_filter_orderby_and_DefaultIfEmpty(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.GroupJoin_SelectMany_subquery_with_filter_orderby_and_DefaultIfEmpty(async))).Message); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs index ae0b1342950..a6c6c770ea5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs @@ -173,7 +173,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableIntA" = "e"."IntB" AND "e"."NullableIntA" IS NOT NULL +WHERE "e"."NullableIntA" = "e"."IntB" """, // """ @@ -184,7 +184,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."IntA" = "e"."NullableIntB" AND "e"."NullableIntB" IS NOT NULL +WHERE "e"."IntA" = "e"."NullableIntB" """, // """ @@ -195,7 +195,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableIntA" = "e"."NullableIntB" AND "e"."NullableIntA" IS NOT NULL AND "e"."NullableIntB" IS NOT NULL) OR ("e"."NullableIntA" IS NULL AND "e"."NullableIntB" IS NULL) +WHERE "e"."NullableIntA" = "e"."NullableIntB" OR ("e"."NullableIntA" IS NULL AND "e"."NullableIntB" IS NULL) """); } @@ -751,7 +751,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL +WHERE "e"."BoolA" = "e"."NullableBoolB" """, // """ @@ -773,7 +773,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL +WHERE "e"."BoolA" <> "e"."NullableBoolB" """, // """ @@ -784,7 +784,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL +WHERE "e"."NullableBoolA" = "e"."BoolB" """, // """ @@ -795,7 +795,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" = "e"."NullableBoolB" AND "e"."NullableBoolA" IS NOT NULL AND "e"."NullableBoolB" IS NOT NULL) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -806,7 +806,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL +WHERE "e"."NullableBoolA" <> "e"."BoolB" """, // """ @@ -817,7 +817,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolA" IS NOT NULL AND "e"."NullableBoolB" IS NOT NULL) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -839,7 +839,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL +WHERE "e"."BoolA" <> "e"."NullableBoolB" """, // """ @@ -861,7 +861,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL +WHERE "e"."BoolA" = "e"."NullableBoolB" """, // """ @@ -872,7 +872,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL +WHERE "e"."NullableBoolA" <> "e"."BoolB" """, // """ @@ -883,7 +883,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolA" IS NOT NULL AND "e"."NullableBoolB" IS NOT NULL) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -894,7 +894,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL +WHERE "e"."NullableBoolA" = "e"."BoolB" """, // """ @@ -905,7 +905,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" = "e"."NullableBoolB" AND "e"."NullableBoolA" IS NOT NULL AND "e"."NullableBoolB" IS NOT NULL) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """); }