diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 064e97cbe74..333f58c7079 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -660,20 +660,10 @@ private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpressi 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), diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index a05a69773f8..3176f5f5968 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -166,6 +166,7 @@ SqlExpression ProcessJoinPredicate(SqlExpression predicate) right, leftNullable, rightNullable, + optimize: true, out _); return result; @@ -1107,6 +1108,7 @@ protected virtual SqlExpression VisitSqlBinary( right, leftNullable, rightNullable, + optimize, out nullable); if (optimized is SqlUnaryExpression { Operand: ColumnExpression optimizedUnaryColumnOperand } optimizedUnary) @@ -1124,7 +1126,7 @@ protected virtual SqlExpression VisitSqlBinary( // we assume that NullSemantics rewrite is only needed (on the current level) // if the optimization didn't make any changes. // Reason is that optimization can/will change the nullability of the resulting expression - // and that inforation is not tracked/stored anywhere + // and that information is not tracked/stored anywhere // so we can no longer rely on nullabilities that we computed earlier (leftNullable, rightNullable) // when performing null semantics rewrite. // It should be fine because current optimizations *radically* change the expression @@ -1451,6 +1453,7 @@ private SqlExpression OptimizeComparison( SqlExpression right, bool leftNullable, bool rightNullable, + bool optimize, out bool nullable) { var leftNullValue = leftNullable && left is SqlConstantExpression or SqlParameterExpression; @@ -1531,32 +1534,8 @@ private SqlExpression OptimizeComparison( && !rightNullable && sqlBinaryExpression.OperatorType is ExpressionType.Equal or ExpressionType.NotEqual) { - var leftUnary = left as SqlUnaryExpression; - var rightUnary = right as SqlUnaryExpression; - - var leftNegated = IsLogicalNot(leftUnary); - var rightNegated = IsLogicalNot(rightUnary); - - if (leftNegated) - { - left = leftUnary!.Operand; - } - - if (rightNegated) - { - right = rightUnary!.Operand; - } - - // a == b <=> !a == !b -> a == b - // !a == b <=> a == !b -> a != b - // a != b <=> !a != !b -> a != b - // !a != b <=> a != !b -> a == b - nullable = false; - - return sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftNegated == rightNegated - ? _sqlExpressionFactory.NotEqual(left, right) - : _sqlExpressionFactory.Equal(left, right); + return OptimizeBooleanComparison(sqlBinaryExpression, left, right, optimize); } nullable = false; @@ -1564,14 +1543,11 @@ private SqlExpression OptimizeComparison( return sqlBinaryExpression.Update(left, right); } - private SqlExpression RewriteNullSemantics( + private SqlExpression OptimizeBooleanComparison( SqlBinaryExpression sqlBinaryExpression, SqlExpression left, SqlExpression right, - bool leftNullable, - bool rightNullable, - bool optimize, - out bool nullable) + bool optimize) { var leftUnary = left as SqlUnaryExpression; var rightUnary = right as SqlUnaryExpression; @@ -1589,22 +1565,49 @@ private SqlExpression RewriteNullSemantics( right = rightUnary!.Operand; } + var notEqual = sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftNegated == rightNegated; + + // prefer equality in predicates + if (optimize && notEqual && left.Type == typeof(bool)) + { + if (right is ColumnExpression && (left is not ColumnExpression || leftNegated)) + { + left = _sqlExpressionFactory.Not(left); + } + else + { + right = _sqlExpressionFactory.Not(right); + } + + return _sqlExpressionFactory.Equal(left, right); + } + + // a == b <=> !a == !b -> a == b + // !a == b <=> a == !b -> a != b + // a != b <=> !a != !b -> a != b + // !a != b <=> a != !b -> a == b + + return notEqual + ? _sqlExpressionFactory.NotEqual(left, right) + : _sqlExpressionFactory.Equal(left, right); + } + + private SqlExpression RewriteNullSemantics( + SqlBinaryExpression sqlBinaryExpression, + SqlExpression left, + SqlExpression right, + bool leftNullable, + bool rightNullable, + bool optimize, + out bool nullable) + { var leftIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(left), leftNullable); - var leftIsNotNull = _sqlExpressionFactory.Not(leftIsNull); + var leftIsNotNull = OptimizeNotExpression(_sqlExpressionFactory.Not(leftIsNull)); var rightIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(right), rightNullable); - var rightIsNotNull = _sqlExpressionFactory.Not(rightIsNull); + var rightIsNotNull = OptimizeNotExpression(_sqlExpressionFactory.Not(rightIsNull)); - SqlExpression body; - if (leftNegated == rightNegated) - { - body = _sqlExpressionFactory.Equal(left, right); - } - else - { - // a == !b and !a == b in SQL evaluate the same as a != b - body = _sqlExpressionFactory.NotEqual(left, right); - } + var body = OptimizeBooleanComparison(sqlBinaryExpression, left, right, optimize); // optimized expansion which doesn't distinguish between null and false if (optimize && sqlBinaryExpression.OperatorType == ExpressionType.Equal) @@ -1617,6 +1620,12 @@ private SqlExpression RewriteNullSemantics( // doing a full null semantics rewrite - removing all nulls from truth table nullable = false; + if (sqlBinaryExpression.OperatorType == ExpressionType.NotEqual) + { + // the factory takes care of simplifying equal <-> not-equal + body = _sqlExpressionFactory.Not(body); + } + // (a == b && (a != null && b != null)) || (a == null && b == null) body = _sqlExpressionFactory.OrElse( _sqlExpressionFactory.AndAlso(body, _sqlExpressionFactory.AndAlso(leftIsNotNull, rightIsNotNull)), @@ -1625,7 +1634,7 @@ private SqlExpression RewriteNullSemantics( if (sqlBinaryExpression.OperatorType == ExpressionType.NotEqual) { // the factory takes care of simplifying using DeMorgan - body = _sqlExpressionFactory.Not(body); + body = OptimizeNotExpression(_sqlExpressionFactory.Not(body)); } return body; @@ -1643,18 +1652,40 @@ protected virtual SqlExpression OptimizeNotExpression(SqlExpression expression) return expression; } - // !(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)) + if (sqlUnaryExpression.Operand is SqlBinaryExpression sqlBinaryOperand) { - return _sqlExpressionFactory.MakeBinary( - negated, - sqlBinaryOperand.Left, - sqlBinaryOperand.Right, - sqlBinaryOperand.TypeMapping)!; + // !(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)!; + } + + // use equality where possible - at this point (true == null) and (false == null) have been converted to + // IS NULL / IS NOT NULL (i.e. false), so this optimization is safe to do. See #35393 + // !(a == true) -> a == false + // !(a == false) -> a == true + if (sqlBinaryOperand is { OperatorType: ExpressionType.Equal, Right: SqlConstantExpression { Value: bool } }) + { + return _sqlExpressionFactory.Equal( + sqlBinaryOperand.Left, + OptimizeNotExpression(_sqlExpressionFactory.Not(sqlBinaryOperand.Right))); + } + + // !(true == a) -> false == a + // !(false == a) -> true == a + if (sqlBinaryOperand is { OperatorType: ExpressionType.Equal, Left: SqlConstantExpression { Value: bool } }) + { + return _sqlExpressionFactory.Equal( + OptimizeNotExpression(_sqlExpressionFactory.Not(sqlBinaryOperand.Left)), + sqlBinaryOperand.Right); + } } // the factory can optimize most `NOT` expressions @@ -2039,7 +2070,7 @@ private SqlExpression ProcessNullNotNull(SqlExpression sqlExpression, bool opera return result; } } - break; + break; } return sqlUnaryExpression; diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs index 6ce93abfd78..c20257949ad 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs @@ -2459,6 +2459,25 @@ await AssertQueryScalar( ss => ss.Set().Where(e => true).Select(e => e.Id)); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Compare_constant_true_to_nullable_column_negated(bool async) + => await AssertQueryScalar( + async, + ss => ss.Set().Where(x => !(true == x.NullableBoolA)).Select(x => x.Id)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Compare_constant_true_to_expression_which_evaluates_to_null(bool async) + { + var prm = default(bool?); + + await AssertQueryScalar( + async, + ss => ss.Set().Where(x => x.NullableBoolA != null + && !object.Equals(true, x.NullableBoolA == null ? null : prm)).Select(x => x.Id)); + } + // We can't client-evaluate Like (for the expected results). // However, since the test data has no LIKE wildcards, it effectively functions like equality - except that 'null like null' returns // false instead of true. So we have this "lite" implementation which doesn't support wildcards. diff --git a/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs index 4e602af3a4f..6b7cb03fb2a 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs @@ -703,6 +703,24 @@ public virtual Task GroupJoin_aggregate_nested_anonymous_key_selectors(bool asyn (c, g) => new { c.CustomerID, Sum = g.Sum(x => x.CustomerID.Length) }), elementSorter: e => e.CustomerID)); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupJoin_on_true_equal_true(bool async) + => AssertQuery( + async, + ss => ss.Set().GroupJoin( + ss.Set(), + x => true, + x => true, + (c, g) => new { c, g }) + .Select(x => new { x.c.CustomerID, Orders = x.g }), + elementSorter: e => e.CustomerID, + elementAsserter: (e, a) => + { + Assert.Equal(e.CustomerID, a.CustomerID); + AssertCollection(e.Orders, a.Orders, elementSorter: ee => ee.OrderID); + }); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Inner_join_with_tautology_predicate_converts_to_cross_join(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs index 69f02149536..14af7a25c2d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs @@ -1369,10 +1369,10 @@ public override async Task Where_navigation_property_to_collection(bool async) SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [LevelThree] AS [l1] - WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0 + WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) """); } @@ -1385,10 +1385,10 @@ public override async Task Where_navigation_property_to_collection2(bool async) SELECT [l].[Id], [l].[Level2_Optional_Id], [l].[Level2_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse3Id], [l].[OneToMany_Optional_Self_Inverse3Id], [l].[OneToMany_Required_Inverse3Id], [l].[OneToMany_Required_Self_Inverse3Id], [l].[OneToOne_Optional_PK_Inverse3Id], [l].[OneToOne_Optional_Self3Id] FROM [LevelThree] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Level2_Required_Id] = [l0].[Id] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [LevelThree] AS [l1] - WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0 + WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs index 075eaf6fffa..0a59d9aed93 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs @@ -5055,8 +5055,8 @@ WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] ) AS [l5] ON [l3].[Level2_Required_Id] = 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 -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 [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ( - SELECT COUNT(*) +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 [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND EXISTS ( + SELECT 1 FROM [Level1] AS [l6] WHERE [l6].[Level2_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse3Id] IS NOT NULL 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] @@ -5064,7 +5064,7 @@ END IS NOT NULL 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 = [l6].[OneToMany_Optional_Inverse3Id] OR (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 [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0 + END IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) """); } @@ -6255,8 +6255,8 @@ LEFT JOIN ( FROM [Level1] AS [l0] WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] IS NOT NULL AND [l0].[OneToMany_Required_Inverse2Id] IS NOT NULL ) AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id] -WHERE ( - SELECT COUNT(*) +WHERE 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] @@ -6264,7 +6264,7 @@ 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))) > 0 + END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs index 81db1893717..792590d945c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs @@ -556,9 +556,9 @@ public override async Task String_ends_with_not_equals_nullable_column(bool asyn FROM [FunkyCustomers] AS [f] CROSS JOIN [FunkyCustomers] AS [f0] WHERE CASE - WHEN [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] THEN CAST(1 AS bit) + WHEN [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR RIGHT([f].[FirstName], LEN([f0].[LastName])) <> [f0].[LastName] THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> [f].[NullableBool] OR [f].[NullableBool] IS NULL +END = [f].[NullableBool] OR [f].[NullableBool] IS NULL """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs index 1cf8bdb95a3..8dad1faf508 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs @@ -556,9 +556,9 @@ public override async Task String_ends_with_not_equals_nullable_column(bool asyn FROM [FunkyCustomers] AS [f] CROSS JOIN [FunkyCustomers] AS [f0] WHERE CASE - WHEN [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] THEN CAST(1 AS bit) + WHEN [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR RIGHT([f].[FirstName], LEN([f0].[LastName])) <> [f0].[LastName] THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> [f].[NullableBool] OR [f].[NullableBool] IS NULL +END = [f].[NullableBool] OR [f].[NullableBool] IS NULL """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index d12c45997f3..d3b75332e92 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -6217,7 +6217,7 @@ FROM [Gears] AS [g] LEFT JOIN ( SELECT [w].[Id], [w].[OwnerFullName] FROM [Weapons] AS [w] - WHERE [w].[IsAutomatic] <> @isAutomatic + WHERE [w].[IsAutomatic] = ~@isAutomatic ) AS [w0] ON [g].[FullName] = [w0].[OwnerFullName] """); } @@ -6941,7 +6941,7 @@ public override async Task Logical_operation_with_non_null_parameter_optimizes_n SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank] FROM [Gears] AS [g] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """, // """ @@ -6949,7 +6949,7 @@ WHERE [g].[HasSoulPatch] <> @prm SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank] FROM [Gears] AS [g] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs index c8486b8e9f9..0515e690f8c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs @@ -616,6 +616,22 @@ public override async Task GroupJoin_aggregate_nested_anonymous_key_selectors(bo AssertSql(); } + public override async Task GroupJoin_on_true_equal_true(bool async) + { + await base.GroupJoin_on_true_equal_true(async); + + AssertSql( +""" +SELECT [c].[CustomerID], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] +FROM [Customers] AS [c] +OUTER APPLY ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] + FROM [Orders] AS [o] +) AS [o0] +ORDER BY [c].[CustomerID] +"""); + } + public override async Task Inner_join_with_tautology_predicate_converts_to_cross_join(bool async) { await base.Inner_join_with_tautology_predicate_converts_to_cross_join(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs index c8baa1104c4..00ab68efe41 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs @@ -1091,7 +1091,7 @@ public override async Task Where_not_bool_member_compared_to_binary_expression(b """ SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock] FROM [Products] AS [p] -WHERE [p].[Discontinued] <> CASE +WHERE [p].[Discontinued] = ~CASE WHEN [p].[ProductID] > 50 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END @@ -1125,7 +1125,7 @@ FROM [Products] AS [p] WHERE CASE WHEN [p].[ProductID] > 50 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> @prm +END = ~@prm """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs index d771cc25f85..6346d1acc3e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs @@ -272,7 +272,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ @@ -286,7 +286,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] """, // """ @@ -328,7 +328,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] """, // """ @@ -342,7 +342,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """, // """ @@ -353,7 +353,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ @@ -367,7 +367,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] """, // """ @@ -406,7 +406,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] """, // """ @@ -420,7 +420,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """, // """ @@ -459,7 +459,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ @@ -473,7 +473,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ @@ -512,7 +512,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ @@ -526,7 +526,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """, // """ @@ -590,7 +590,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ @@ -604,7 +604,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ @@ -646,7 +646,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ @@ -660,7 +660,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE (~[e].[NullableBoolA] = [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """, // """ @@ -671,7 +671,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ @@ -685,7 +685,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ @@ -724,7 +724,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ @@ -738,7 +738,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """, // """ @@ -802,7 +802,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ @@ -816,7 +816,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ @@ -858,7 +858,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ @@ -872,7 +872,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE (~[e].[NullableBoolA] = [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """, // """ @@ -908,7 +908,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ @@ -922,7 +922,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] """, // """ @@ -964,7 +964,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] """, // """ @@ -978,7 +978,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """, // """ @@ -989,7 +989,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ @@ -1003,7 +1003,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] """, // """ @@ -1042,7 +1042,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] """, // """ @@ -1056,7 +1056,7 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """, // """ @@ -1126,25 +1126,25 @@ public override async Task Compare_negated_bool_with_bool_equal(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """); } @@ -1156,25 +1156,25 @@ public override async Task Compare_bool_with_negated_bool_equal(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """); } @@ -1216,25 +1216,25 @@ public override async Task Compare_bool_with_bool_equal_negated(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1306,25 +1306,25 @@ public override async Task Compare_negated_bool_with_negated_bool_equal_negated( """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE (~[e].[NullableBoolA] = [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1336,25 +1336,25 @@ public override async Task Compare_bool_with_bool_not_equal(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1426,25 +1426,25 @@ public override async Task Compare_negated_bool_with_negated_bool_not_equal(bool """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE (~[e].[NullableBoolA] = [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1486,25 +1486,25 @@ public override async Task Compare_negated_bool_with_bool_not_equal_negated(bool """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE ~[e].[BoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """); } @@ -1516,25 +1516,25 @@ public override async Task Compare_bool_with_negated_bool_not_equal_negated(bool """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] 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) """); } @@ -1636,25 +1636,25 @@ public override async Task Compare_equals_method_negated(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1666,25 +1666,25 @@ public override async Task Compare_equals_method_negated_static(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = ~[e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) """); } @@ -1732,7 +1732,7 @@ public override async Task Compare_complex_equal_not_equal_equal(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] ^ [e].[BoolB] <> CAST([e].[IntA] ^ [e].[IntB] AS bit) +WHERE ~([e].[BoolA] ^ [e].[BoolB]) = CAST([e].[IntA] ^ [e].[IntB] AS bit) """, // """ @@ -1741,8 +1741,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL THEN CAST(1 AS bit) +END = CASE + WHEN [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -1753,8 +1753,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN ([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) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN ([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) THEN CAST(1 AS bit) +END = CASE + WHEN ([e].[NullableIntA] <> [e].[NullableIntB] OR [e].[NullableIntA] IS NULL OR [e].[NullableIntB] IS NULL) AND ([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -1804,7 +1804,7 @@ public override async Task Compare_complex_not_equal_not_equal_equal(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] ^ [e].[BoolB] <> ~CAST([e].[IntA] ^ [e].[IntB] AS bit) +WHERE [e].[BoolA] ^ [e].[BoolB] = CAST([e].[IntA] ^ [e].[IntB] AS bit) """, // """ @@ -1813,8 +1813,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL THEN CAST(1 AS bit) +END = CASE + WHEN [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -1825,8 +1825,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN ([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) THEN CAST(1 AS bit) +END = CASE + WHEN ([e].[NullableIntA] <> [e].[NullableIntB] OR [e].[NullableIntA] IS NULL OR [e].[NullableIntB] IS NULL) AND ([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -1876,7 +1876,7 @@ public override async Task Compare_complex_not_equal_not_equal_not_equal(bool as """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] ^ [e].[BoolB] <> CAST([e].[IntA] ^ [e].[IntB] AS bit) +WHERE [e].[BoolA] ^ [e].[BoolB] = ~CAST([e].[IntA] ^ [e].[IntB] AS bit) """, // """ @@ -1885,8 +1885,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) +END = CASE + WHEN [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -1897,8 +1897,8 @@ FROM [Entities1] AS [e] WHERE CASE WHEN ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END <> CASE - WHEN ([e].[NullableIntA] <> [e].[NullableIntB] OR [e].[NullableIntA] IS NULL OR [e].[NullableIntB] IS NULL) AND ([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) THEN CAST(1 AS bit) +END = CASE + WHEN ([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) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -2779,13 +2779,13 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE COALESCE([e].[NullableBoolB], [e].[BoolC]) <> [e].[NullableBoolA] OR [e].[NullableBoolA] IS NULL +WHERE ~COALESCE([e].[NullableBoolB], [e].[BoolC]) = [e].[NullableBoolA] OR [e].[NullableBoolA] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE (COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) <> [e].[NullableBoolA] OR ([e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL) OR [e].[NullableBoolA] IS NULL) AND ([e].[NullableBoolB] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL OR [e].[NullableBoolA] IS NOT NULL) +WHERE (~COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) = [e].[NullableBoolA] OR ([e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL) OR [e].[NullableBoolA] IS NULL) AND ([e].[NullableBoolB] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL OR [e].[NullableBoolA] IS NOT NULL) """); } @@ -2807,7 +2807,7 @@ ELSE [e].[NullableBoolC] SELECT [e].[Id] FROM [Entities1] AS [e] WHERE CASE - WHEN ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) THEN [e].[BoolB] + WHEN ([e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) THEN [e].[BoolB] ELSE [e].[BoolC] END = [e].[BoolA] """, @@ -2816,13 +2816,13 @@ ELSE [e].[BoolC] SELECT [e].[Id] FROM [Entities1] AS [e] WHERE CASE - WHEN CASE + WHEN ~CASE WHEN [e].[BoolA] = CAST(1 AS bit) THEN CASE WHEN ([e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolB] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END ELSE [e].[BoolC] - END <> [e].[BoolB] THEN [e].[BoolA] + END = [e].[BoolB] THEN [e].[BoolA] WHEN [e].[NullableBoolB] = [e].[NullableBoolC] OR ([e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END = CAST(1 AS bit) @@ -3503,13 +3503,13 @@ public override async Task Null_semantics_with_null_check_complex2(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND ([e].[NullableBoolB] <> [e].[NullableBoolA] OR [e].[NullableBoolC] IS NOT NULL) AND ([e].[NullableBoolC] <> [e].[NullableBoolB] OR [e].[NullableBoolC] IS NULL)) OR [e].[NullableBoolC] <> [e].[BoolB] OR [e].[NullableBoolC] IS NULL +WHERE ([e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND ([e].[NullableBoolB] = ~[e].[NullableBoolA] OR [e].[NullableBoolC] IS NOT NULL) AND ([e].[NullableBoolC] = ~[e].[NullableBoolB] OR [e].[NullableBoolC] IS NULL)) OR [e].[NullableBoolC] = ~[e].[BoolB] OR [e].[NullableBoolC] IS NULL """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE ([e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND ([e].[NullableBoolB] <> [e].[NullableBoolA] OR [e].[NullableBoolC] IS NOT NULL) AND ([e].[NullableBoolC] <> [e].[NullableBoolB] OR [e].[NullableBoolC] IS NULL)) OR [e].[NullableBoolB] <> [e].[BoolB] OR [e].[NullableBoolB] IS NULL +WHERE ([e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND ([e].[NullableBoolB] = ~[e].[NullableBoolA] OR [e].[NullableBoolC] IS NOT NULL) AND ([e].[NullableBoolC] = ~[e].[NullableBoolB] OR [e].[NullableBoolC] IS NULL)) OR [e].[NullableBoolB] = ~[e].[BoolB] OR [e].[NullableBoolB] IS NULL """); } @@ -3728,7 +3728,7 @@ public override async Task Nullable_column_info_doesnt_propagate_between_differe SELECT [e].[Id] FROM [Entities1] AS [e] INNER JOIN [Entities1] AS [e0] ON [e].[NullableBoolA] IS NULL -WHERE ([e].[NullableBoolA] <> [e0].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e0].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e0].[NullableBoolB] IS NOT NULL) +WHERE ([e].[NullableBoolA] = ~[e0].[NullableBoolB] OR [e].[NullableBoolA] IS NULL OR [e0].[NullableBoolB] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e0].[NullableBoolB] IS NOT NULL) """); } @@ -3740,7 +3740,7 @@ public override async Task Nullable_column_info_propagation_complex(bool async) """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableStringA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND [e].[NullableStringC] IS NOT NULL AND ([e].[NullableBoolB] <> [e].[NullableBoolC] OR [e].[NullableBoolC] IS NULL) +WHERE [e].[NullableStringA] IS NOT NULL AND [e].[NullableBoolB] IS NOT NULL AND [e].[NullableStringC] IS NOT NULL AND ([e].[NullableBoolB] = ~[e].[NullableBoolC] OR [e].[NullableBoolC] IS NULL) """); } @@ -4145,8 +4145,8 @@ WHERE [e].[NullableBoolA] IS NULL 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 @prm <> CASE - WHEN [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) +WHERE @prm = CASE + WHEN [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -4154,8 +4154,8 @@ ELSE CAST(0 AS bit) """ 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].[BoolB] <> CASE - WHEN [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) +WHERE [e].[BoolB] = CASE + WHEN [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -4177,8 +4177,8 @@ WHERE [e].[NullableIntA] IS NULL 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 @prm <> CASE - WHEN [e].[NullableIntA] IS NOT NULL THEN CAST(1 AS bit) +WHERE @prm = CASE + WHEN [e].[NullableIntA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -4186,8 +4186,8 @@ ELSE CAST(0 AS bit) """ 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].[BoolB] <> CASE - WHEN [e].[NullableIntA] IS NOT NULL THEN CAST(1 AS bit) +WHERE [e].[BoolB] = CASE + WHEN [e].[NullableIntA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -4209,8 +4209,8 @@ WHERE [e].[NullableBoolA] IS NOT NULL 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 @prm <> CASE - WHEN [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) +WHERE @prm = CASE + WHEN [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """); @@ -4247,8 +4247,8 @@ public override async Task Comparison_compared_to_null_check_on_bool(bool async) """ 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 ~CAST([e].[IntA] ^ [e].[IntB] AS bit) <> CASE - WHEN [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) +WHERE ~CAST([e].[IntA] ^ [e].[IntB] AS bit) = CASE + WHEN [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END """, @@ -4381,10 +4381,10 @@ public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullab FROM [Entities1] AS [e] WHERE [e].[NullableBoolA] IS NULL OR CASE WHEN [e].[NullableBoolB] IS NULL THEN CASE - WHEN [e].[NullableBoolB] <> [e].[NullableBoolA] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolB] = ~[e].[NullableBoolA] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END - WHEN [e].[NullableBoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END = CAST(1 AS bit) """); @@ -4402,10 +4402,10 @@ FROM [Entities1] AS [e] WHERE CASE WHEN [e].[NullableBoolA] IS NULL THEN ~([e].[BoolA] ^ [e].[BoolB]) WHEN [e].[NullableBoolC] IS NULL THEN CASE - WHEN ([e].[NullableBoolA] <> [e].[NullableBoolC] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolC] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL) THEN CAST(1 AS bit) + WHEN ([e].[NullableBoolA] = ~[e].[NullableBoolC] OR [e].[NullableBoolA] IS NULL OR [e].[NullableBoolC] IS NULL) AND ([e].[NullableBoolA] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END - WHEN ([e].[NullableBoolC] <> [e].[NullableBoolA] OR [e].[NullableBoolC] IS NULL OR [e].[NullableBoolA] IS NULL) AND ([e].[NullableBoolC] IS NOT NULL OR [e].[NullableBoolA] IS NOT NULL) THEN CAST(1 AS bit) + WHEN ([e].[NullableBoolC] = ~[e].[NullableBoolA] OR [e].[NullableBoolC] IS NULL OR [e].[NullableBoolA] IS NULL) AND ([e].[NullableBoolC] IS NOT NULL OR [e].[NullableBoolA] IS NOT NULL) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END = CAST(1 AS bit) """); @@ -4568,6 +4568,30 @@ FROM [Entities1] AS [e] """); } + public async override Task Compare_constant_true_to_nullable_column_negated(bool async) + { + await base.Compare_constant_true_to_nullable_column_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CAST(0 AS bit) = [e].[NullableBoolA] OR [e].[NullableBoolA] IS NULL +"""); + } + + public override async Task Compare_constant_true_to_expression_which_evaluates_to_null(bool async) + { + await base.Compare_constant_true_to_expression_which_evaluates_to_null(async); + + AssertSql( +""" +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] IS NOT NULL +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 182be105b6d..bf8a99c63ea 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -9285,7 +9285,7 @@ UNION ALL SELECT [o].[Nickname], [o].[SquadId], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName], [o].[HasSoulPatch], [o].[LeaderNickname], [o].[LeaderSquadId], [o].[Rank], N'Officer' AS [Discriminator] FROM [Officers] AS [o] ) AS [u] -WHERE [u].[HasSoulPatch] <> @prm +WHERE [u].[HasSoulPatch] = ~@prm """, // """ @@ -9299,7 +9299,7 @@ UNION ALL SELECT [o].[Nickname], [o].[SquadId], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName], [o].[HasSoulPatch], [o].[LeaderNickname], [o].[LeaderSquadId], [o].[Rank], N'Officer' AS [Discriminator] FROM [Officers] AS [o] ) AS [u] -WHERE [u].[HasSoulPatch] <> @prm +WHERE [u].[HasSoulPatch] = ~@prm """); } @@ -11060,7 +11060,7 @@ FROM [Officers] AS [o] LEFT JOIN ( SELECT [w].[Id], [w].[OwnerFullName] FROM [Weapons] AS [w] - WHERE [w].[IsAutomatic] <> @isAutomatic + WHERE [w].[IsAutomatic] = ~@isAutomatic ) AS [w0] ON [u].[FullName] = [w0].[OwnerFullName] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 62be1d75c6a..8d39cefb6db 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -7885,7 +7885,7 @@ WHEN [o].[Nickname] IS NOT NULL THEN N'Officer' END AS [Discriminator] FROM [Gears] AS [g] LEFT JOIN [Officers] AS [o] ON [g].[Nickname] = [o].[Nickname] AND [g].[SquadId] = [o].[SquadId] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """, // """ @@ -7896,7 +7896,7 @@ WHEN [o].[Nickname] IS NOT NULL THEN N'Officer' END AS [Discriminator] FROM [Gears] AS [g] LEFT JOIN [Officers] AS [o] ON [g].[Nickname] = [o].[Nickname] AND [g].[SquadId] = [o].[SquadId] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """); } @@ -9358,7 +9358,7 @@ FROM [Gears] AS [g] LEFT JOIN ( SELECT [w].[Id], [w].[OwnerFullName] FROM [Weapons] AS [w] - WHERE [w].[IsAutomatic] <> @isAutomatic + WHERE [w].[IsAutomatic] = ~@isAutomatic ) AS [w0] ON [g].[FullName] = [w0].[OwnerFullName] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index 727f120e502..d612b504201 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -1482,7 +1482,7 @@ END AS [Collection] LEFT JOIN ( SELECT [w].[Id], [w].[OwnerFullName] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] - WHERE [w].[IsAutomatic] <> @isAutomatic + WHERE [w].[IsAutomatic] = ~@isAutomatic ) AS [w0] ON [g].[FullName] = [w0].[OwnerFullName] """); } @@ -2020,7 +2020,7 @@ public override async Task Logical_operation_with_non_null_parameter_optimizes_n SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """, // """ @@ -2028,7 +2028,7 @@ WHERE [g].[HasSoulPatch] <> @prm SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] -WHERE [g].[HasSoulPatch] <> @prm +WHERE [g].[HasSoulPatch] = ~@prm """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs index fc64367a6c3..e59ee370231 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs @@ -87,7 +87,7 @@ public override async Task Where_bool_with_value_conversion_inside_comparison_do """ SELECT "b"."BlogId", "b"."Discriminator", "b"."IndexerVisible", "b"."IsVisible", "b"."Url", "b"."RssUrl" FROM "Blog" AS "b" -WHERE "b"."IsVisible" <> 'Y' +WHERE "b"."IsVisible" = 'N' """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 6038f2f2c53..3deb2933052 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -414,7 +414,7 @@ public override async Task Logical_operation_with_non_null_parameter_optimizes_n SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank" FROM "Gears" AS "g" -WHERE "g"."HasSoulPatch" <> @prm +WHERE "g"."HasSoulPatch" = (NOT (@prm)) """, // """ @@ -422,7 +422,7 @@ public override async Task Logical_operation_with_non_null_parameter_optimizes_n SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank" FROM "Gears" AS "g" -WHERE "g"."HasSoulPatch" <> @prm +WHERE "g"."HasSoulPatch" = (NOT (@prm)) """); } @@ -7086,7 +7086,7 @@ public override async Task SelectMany_Where_DefaultIfEmpty_with_navigation_in_th LEFT JOIN ( SELECT "w"."Id", "w"."OwnerFullName" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" <> @isAutomatic + WHERE "w"."IsAutomatic" = (NOT (@isAutomatic)) ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs index 7051721f131..f032b5b7bcd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs @@ -57,4 +57,10 @@ 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_on_true_equal_true(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.GroupJoin_on_true_equal_true(async))).Message); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs index 5a1487ffb76..2ad71f39ae9 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs @@ -232,7 +232,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE (NOT ("e"."BoolA")) = "e"."BoolB" """, // """ @@ -243,7 +243,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" """, // """ @@ -276,7 +276,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" """, // """ @@ -287,7 +287,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE (NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -298,7 +298,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."BoolA" = (NOT ("e"."BoolB")) """, // """ @@ -309,7 +309,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) """, // """ @@ -342,7 +342,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) """, // """ @@ -353,7 +353,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -386,7 +386,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."BoolA" = (NOT ("e"."BoolB")) """, // """ @@ -397,7 +397,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolB" IS NULL """, // """ @@ -430,7 +430,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) OR "e"."NullableBoolA" IS NULL """, // """ @@ -441,7 +441,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) +WHERE ("e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) """, // """ @@ -496,7 +496,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE (NOT ("e"."BoolA")) = "e"."BoolB" """, // """ @@ -507,7 +507,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ @@ -540,7 +540,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" OR "e"."NullableBoolA" IS NULL """, // """ @@ -551,7 +551,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) +WHERE ((NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) """, // """ @@ -562,7 +562,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."BoolA" = (NOT ("e"."BoolB")) """, // """ @@ -573,7 +573,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolB" IS NULL """, // """ @@ -606,7 +606,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) OR "e"."NullableBoolA" IS NULL """, // """ @@ -617,7 +617,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) +WHERE ("e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) """, // """ @@ -672,7 +672,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE (NOT ("e"."BoolA")) = "e"."BoolB" """, // """ @@ -683,7 +683,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ @@ -716,7 +716,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" OR "e"."NullableBoolA" IS NULL """, // """ @@ -727,7 +727,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) +WHERE ((NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) """, // """ @@ -760,7 +760,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE (NOT ("e"."BoolA")) = "e"."BoolB" """, // """ @@ -771,7 +771,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" """, // """ @@ -804,7 +804,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" """, // """ @@ -815,7 +815,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE (NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -826,7 +826,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."BoolA" = (NOT ("e"."BoolB")) """, // """ @@ -837,7 +837,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) """, // """ @@ -870,7 +870,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) """, // """ @@ -881,7 +881,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) """, // """ @@ -973,7 +973,7 @@ public override async Task Null_semantics_conditional(bool async) SELECT "e"."Id" FROM "Entities1" AS "e" WHERE CASE - WHEN ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) THEN "e"."BoolB" + WHEN ("e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) THEN "e"."BoolB" ELSE "e"."BoolC" END = "e"."BoolA" """, @@ -982,10 +982,10 @@ WHERE CASE SELECT "e"."Id" FROM "Entities1" AS "e" WHERE CASE - WHEN CASE + WHEN (NOT (CASE WHEN "e"."BoolA" THEN ("e"."NullableBoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolA" IS NULL OR "e"."NullableBoolB" IS NULL) AND ("e"."NullableBoolA" IS NOT NULL OR "e"."NullableBoolB" IS NOT NULL) ELSE "e"."BoolC" - END <> "e"."BoolB" THEN "e"."BoolA" + END)) = "e"."BoolB" THEN "e"."BoolA" ELSE "e"."NullableBoolB" = "e"."NullableBoolC" OR ("e"."NullableBoolB" IS NULL AND "e"."NullableBoolC" IS NULL) END """, @@ -1262,13 +1262,13 @@ public override async Task Bool_not_equal_nullable_bool_HasValue(bool async) 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 @prm <> ("e"."NullableBoolA" IS NOT NULL) +WHERE @prm = ("e"."NullableBoolA" IS NULL) """, // """ 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"."BoolB" <> ("e"."NullableBoolA" IS NOT NULL) +WHERE "e"."BoolB" = ("e"."NullableBoolA" IS NULL) """); } @@ -1288,13 +1288,13 @@ public override async Task Bool_not_equal_nullable_int_HasValue(bool async) 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 @prm <> ("e"."NullableIntA" IS NOT NULL) +WHERE @prm = ("e"."NullableIntA" IS NULL) """, // """ 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"."BoolB" <> ("e"."NullableIntA" IS NOT NULL) +WHERE "e"."BoolB" = ("e"."NullableIntA" IS NULL) """); } @@ -1314,7 +1314,7 @@ public override async Task Bool_not_equal_nullable_bool_compared_to_null(bool as 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 @prm <> ("e"."NullableBoolA" IS NOT NULL) +WHERE @prm = ("e"."NullableBoolA" IS NULL) """); } @@ -1437,7 +1437,7 @@ public override async Task Comparison_compared_to_null_check_on_bool(bool async) """ 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"."IntA" = "e"."IntB") <> ("e"."NullableBoolA" IS NOT NULL) +WHERE ("e"."IntA" = "e"."IntB") = ("e"."NullableBoolA" IS NULL) """, // """