From f2154556ad9b3986b27625ab67d19cd55db6a9fb Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Fri, 5 Jul 2024 12:06:08 +0200 Subject: [PATCH 1/8] Prefer equality in boolean comparisons They can take advantage of indexing. --- .../Query/SqlNullabilityProcessor.cs | 89 ++++++++++--------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index a05a69773f8..9a2513e4e6f 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) @@ -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 rightIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(right), rightNullable); var rightIsNotNull = _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)), From 09f58e6f589d6e7ae39e0d4ee144057221054576 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Fri, 5 Jul 2024 12:30:56 +0200 Subject: [PATCH 2/8] Update baselines --- .../Query/FunkyDataQueryAzureSynapseTest.cs | 4 +- .../Query/FunkyDataQuerySqlServerTest.cs | 4 +- .../Query/GearsOfWarQuerySqlServerTest.cs | 6 +- .../Query/NorthwindWhereQuerySqlServerTest.cs | 4 +- .../Query/NullSemanticsQuerySqlServerTest.cs | 224 +++++++++--------- .../Query/TPCGearsOfWarQuerySqlServerTest.cs | 6 +- .../Query/TPTGearsOfWarQuerySqlServerTest.cs | 6 +- .../TemporalGearsOfWarQuerySqlServerTest.cs | 6 +- .../CustomConvertersSqliteTest.cs | 2 +- .../Query/GearsOfWarQuerySqliteTest.cs | 6 +- .../Query/NullSemanticsQuerySqliteTest.cs | 82 +++---- 11 files changed, 175 insertions(+), 175 deletions(-) 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/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..d9f64ba54b7 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) """); 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/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) """, // """ From bc8ac31ae033a4616bf9351eb5798461a59bc8ad Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sat, 13 Jul 2024 19:58:32 +0200 Subject: [PATCH 3/8] Add test to check null rewrites on older SqlServer levels --- .../NullSemanticsQueryOldSqlServerTest.cs | 4576 +++++++++++++++++ 1 file changed, 4576 insertions(+) create mode 100644 test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQueryOldSqlServerTest.cs diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQueryOldSqlServerTest.cs new file mode 100644 index 00000000000..29c8f75990a --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQueryOldSqlServerTest.cs @@ -0,0 +1,4576 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.NullSemanticsModel; + +namespace Microsoft.EntityFrameworkCore.Query; + +#nullable disable + +public class NullSemanticsQueryOldSqlServerTest : NullSemanticsQueryTestBase< + NullSemanticsQueryOldSqlServerTest.NullSemanticsQueryOldSqlServerFixture> +{ + public NullSemanticsQueryOldSqlServerTest(NullSemanticsQueryOldSqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Rewrite_compare_int_with_int(bool async) + { + await base.Rewrite_compare_int_with_int(async); + + AssertSql( + """ +SELECT [e].[Id], ~CAST([e].[IntA] ^ [e].[IntB] AS bit) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableIntA] = [e].[IntB] AND [e].[NullableIntA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = [e].[NullableIntB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id], CAST([e].[IntA] ^ [e].[IntB] AS bit) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableIntA] <> [e].[IntB] OR [e].[NullableIntA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] <> [e].[IntB] OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([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) +""", + // + """ +SELECT [e].[Id], CAST([e].[IntA] ^ [e].[IntB] AS bit) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableIntA] <> [e].[IntB] OR [e].[NullableIntA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] <> [e].[IntB] OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([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) +""", + // + """ +SELECT [e].[Id], ~CAST([e].[IntA] ^ [e].[IntB] AS bit) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableIntA] = [e].[IntB] AND [e].[NullableIntA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = [e].[IntB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[IntA] = [e].[NullableIntB] AND [e].[NullableIntB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = [e].[NullableIntB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +"""); + } + + public override async Task Rewrite_compare_bool_with_bool(bool async) + { + await base.Rewrite_compare_bool_with_bool(async); + + AssertSql( + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id], 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 AS [X] +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) +"""); + } + + public override async Task Compare_bool_with_bool_equal(bool async) + { + await base.Compare_bool_with_bool_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_negated_bool_with_bool_equal(bool async) + { + await base.Compare_negated_bool_with_bool_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_bool_with_negated_bool_equal(bool async) + { + await base.Compare_bool_with_negated_bool_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_negated_bool_with_negated_bool_equal(bool async) + { + await base.Compare_negated_bool_with_negated_bool_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_bool_with_bool_equal_negated(bool async) + { + await base.Compare_bool_with_bool_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_negated_bool_with_bool_equal_negated(bool async) + { + await base.Compare_negated_bool_with_bool_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_bool_with_negated_bool_equal_negated(bool async) + { + await base.Compare_bool_with_negated_bool_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_negated_bool_with_negated_bool_equal_negated(bool async) + { + await base.Compare_negated_bool_with_negated_bool_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_bool_with_bool_not_equal(bool async) + { + await base.Compare_bool_with_bool_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_negated_bool_with_bool_not_equal(bool async) + { + await base.Compare_negated_bool_with_bool_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_bool_with_negated_bool_not_equal(bool async) + { + await base.Compare_bool_with_negated_bool_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_negated_bool_with_negated_bool_not_equal(bool async) + { + await base.Compare_negated_bool_with_negated_bool_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_bool_with_bool_not_equal_negated(bool async) + { + await base.Compare_bool_with_bool_not_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_negated_bool_with_bool_not_equal_negated(bool async) + { + await base.Compare_negated_bool_with_bool_not_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~[e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_bool_with_negated_bool_not_equal_negated(bool async) + { + await base.Compare_bool_with_negated_bool_not_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_negated_bool_with_negated_bool_not_equal_negated(bool async) + { + await base.Compare_negated_bool_with_negated_bool_not_equal_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_equals_method(bool async) + { + await base.Compare_equals_method(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_equals_method_static(bool async) + { + await base.Compare_equals_method_static(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = [e].[NullableBoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Compare_equals_method_negated(bool async) + { + await base.Compare_equals_method_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_equals_method_negated_static(bool async) + { + await base.Compare_equals_method_negated_static(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = ~[e].[BoolB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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 +""", + // + """ +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) +"""); + } + + public override async Task Compare_complex_equal_equal_equal(bool async) + { + await base.Compare_complex_equal_equal_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] ^ [e].[BoolB] = CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Compare_complex_equal_not_equal_equal(bool async) + { + await base.Compare_complex_equal_not_equal_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ~([e].[BoolA] ^ [e].[BoolB]) = CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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] OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +""", + // + """ +SELECT [e].[Id] +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] 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 +"""); + } + + public override async Task Compare_complex_not_equal_equal_equal(bool async) + { + await base.Compare_complex_not_equal_equal_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] ^ [e].[BoolB] = ~CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Compare_complex_not_equal_not_equal_equal(bool async) + { + await base.Compare_complex_not_equal_not_equal_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] ^ [e].[BoolB] = CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Compare_complex_not_equal_equal_not_equal(bool async) + { + await base.Compare_complex_not_equal_equal_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] ^ [e].[BoolB] = CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Compare_complex_not_equal_not_equal_not_equal(bool async) + { + await base.Compare_complex_not_equal_not_equal_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] ^ [e].[BoolB] = ~CAST([e].[IntA] ^ [e].[IntB] AS bit) +""", + // + """ +SELECT [e].[Id] +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Compare_nullable_with_null_parameter_equal(bool async) + { + await base.Compare_nullable_with_null_parameter_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Compare_nullable_with_non_null_parameter_not_equal(bool async) + { + await base.Compare_nullable_with_non_null_parameter_not_equal(async); + + AssertSql( + """ +@prm='Foo' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] = @prm +"""); + } + + public override async Task Join_uses_database_semantics(bool async) + { + await base.Join_uses_database_semantics(async); + + AssertSql( + """ +SELECT [e].[Id] AS [Id1], [e0].[Id] AS [Id2], [e].[NullableIntA], [e0].[NullableIntB] +FROM [Entities1] AS [e] +INNER JOIN [Entities2] AS [e0] ON [e].[NullableIntA] = [e0].[NullableIntB] +"""); + } + + public override async Task Join_uses_csharp_semantics_for_anon_objects(bool async) + { + await base.Join_uses_csharp_semantics_for_anon_objects(async); + + AssertSql( + """ +SELECT [e].[Id] AS [Id1], [e0].[Id] AS [Id2], [e].[NullableIntA], [e0].[NullableIntB] +FROM [Entities1] AS [e] +INNER JOIN [Entities2] AS [e0] ON [e].[NullableIntA] = [e0].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e0].[NullableIntB] IS NULL) +"""); + } + + public override async Task Contains_with_local_array_closure_with_null(bool async) + { + await base.Contains_with_local_array_closure_with_null(async); + + AssertSql( + """ +@ids_without_nulls='["Foo"]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids_without_nulls) AS [i] +) OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Contains_with_local_array_closure_false_with_null(bool async) + { + await base.Contains_with_local_array_closure_false_with_null(async); + + AssertSql( + """ +@ids_without_nulls='["Foo"]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids_without_nulls) AS [i] +) AND [e].[NullableStringA] IS NOT NULL +"""); + } + + public override async Task Contains_with_local_nullable_array_closure_negated(bool async) + { + await base.Contains_with_local_nullable_array_closure_negated(async); + + AssertSql( + """ +@ids='["Foo"]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] nvarchar(max) '$') AS [i] +) OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Contains_with_local_array_closure_with_multiple_nulls(bool async) + { + await base.Contains_with_local_array_closure_with_multiple_nulls(async); + + AssertSql( + """ +@ids_without_nulls='["Foo"]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids_without_nulls) AS [i] +) OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Where_multiple_ors_with_null(bool async) + { + await base.Where_multiple_ors_with_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN (N'Foo', N'Blah') OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Where_multiple_ands_with_null(bool async) + { + await base.Where_multiple_ands_with_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT IN (N'Foo', N'Blah') AND [e].[NullableStringA] IS NOT NULL +"""); + } + + public override async Task Where_multiple_ors_with_nullable_parameter(bool async) + { + await base.Where_multiple_ors_with_nullable_parameter(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] = N'Foo' OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Where_multiple_ands_with_nullable_parameter_and_constant(bool async) + { + await base.Where_multiple_ands_with_nullable_parameter_and_constant(async); + + AssertSql( + """ +@prm3='Blah' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableStringA] <> N'Foo' OR [e].[NullableStringA] IS NULL) AND [e].[NullableStringA] IS NOT NULL AND [e].[NullableStringA] <> @prm3 +"""); + } + + public override async Task Where_multiple_ands_with_nullable_parameter_and_constant_not_optimized(bool async) + { + await base.Where_multiple_ands_with_nullable_parameter_and_constant_not_optimized(async); + + AssertSql( + """ +@prm3='Blah' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringB] IS NOT NULL AND ([e].[NullableStringA] <> N'Foo' OR [e].[NullableStringA] IS NULL) AND [e].[NullableStringA] IS NOT NULL AND [e].[NullableStringA] <> @prm3 +"""); + } + + public override async Task Where_coalesce(bool async) + { + await base.Where_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE COALESCE([e].[NullableBoolA], CAST(1 AS bit)) = CAST(1 AS bit) +"""); + } + + public override async Task Where_equal_nullable_with_null_value_parameter(bool async) + { + await base.Where_equal_nullable_with_null_value_parameter(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Where_not_equal_nullable_with_null_value_parameter(bool async) + { + await base.Where_not_equal_nullable_with_null_value_parameter(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NOT NULL +"""); + } + + public override async Task Where_equal_with_coalesce(bool async) + { + await base.Where_equal_with_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE COALESCE([e].[NullableStringA], [e].[NullableStringB]) = [e].[NullableStringC] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL AND [e].[NullableStringC] IS NULL) +"""); + } + + public override async Task Where_not_equal_with_coalesce(bool async) + { + await base.Where_not_equal_with_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (COALESCE([e].[NullableStringA], [e].[NullableStringB]) <> [e].[NullableStringC] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) OR [e].[NullableStringC] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL OR [e].[NullableStringC] IS NOT NULL) +"""); + } + + public override async Task Where_equal_with_coalesce_both_sides(bool async) + { + await base.Where_equal_with_coalesce_both_sides(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE COALESCE([e].[NullableStringA], [e].[NullableStringB]) = COALESCE([e].[NullableStringC], [e].[StringA]) +"""); + } + + public override async Task Where_not_equal_with_coalesce_both_sides(bool async) + { + await base.Where_not_equal_with_coalesce_both_sides(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (COALESCE([e].[NullableIntA], [e].[NullableIntB]) <> COALESCE([e].[NullableIntC], [e].[NullableIntB]) OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) OR ([e].[NullableIntC] IS NULL AND [e].[NullableIntB] IS NULL)) AND ([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL OR [e].[NullableIntC] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) +"""); + } + + public override async Task Where_equal_with_conditional(bool async) + { + await base.Where_equal_with_conditional(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[NullableStringA] + ELSE [e].[NullableStringB] +END = [e].[NullableStringC] OR (CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[NullableStringA] + ELSE [e].[NullableStringB] +END IS NULL AND [e].[NullableStringC] IS NULL) +"""); + } + + public override async Task Where_not_equal_with_conditional(bool async) + { + await base.Where_not_equal_with_conditional(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableStringC] <> CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[NullableStringA] + ELSE [e].[NullableStringB] +END OR [e].[NullableStringC] IS NULL OR CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[NullableStringA] + ELSE [e].[NullableStringB] +END IS NULL) AND ([e].[NullableStringC] IS NOT NULL OR CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[NullableStringA] + ELSE [e].[NullableStringB] +END IS NOT NULL) +"""); + } + + public override async Task Where_equal_with_conditional_non_nullable(bool async) + { + await base.Where_equal_with_conditional_non_nullable(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringC] <> CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN [e].[StringA] + ELSE [e].[StringB] +END OR [e].[NullableStringC] IS NULL +"""); + } + + public override async Task Where_equal_with_and_and_contains(bool async) + { + await base.Where_equal_with_and_and_contains(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NOT NULL AND [e].[NullableStringB] IS NOT NULL AND (CHARINDEX([e].[NullableStringB], [e].[NullableStringA]) > 0 OR [e].[NullableStringB] LIKE N'') AND [e].[BoolA] = CAST(1 AS bit) +"""); + } + + public override async Task Null_comparison_in_selector_with_relational_nulls(bool async) + { + await base.Null_comparison_in_selector_with_relational_nulls(async); + + AssertSql( + """ +SELECT CASE + WHEN [e].[NullableStringA] <> N'Foo' OR [e].[NullableStringA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Entities1] AS [e] +"""); + } + + public override async Task Null_comparison_in_order_by_with_relational_nulls(bool async) + { + await base.Null_comparison_in_order_by_with_relational_nulls(async); + + AssertSql( + """ +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] +ORDER BY CASE + WHEN [e].[NullableStringA] <> N'Foo' OR [e].[NullableStringA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END, CASE + WHEN [e].[NullableIntB] <> 10 OR [e].[NullableIntB] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Null_comparison_in_join_key_with_relational_nulls(bool async) + { + await base.Null_comparison_in_join_key_with_relational_nulls(async); + + AssertSql( + """ +SELECT [e1].[Id], [e1].[BoolA], [e1].[BoolB], [e1].[BoolC], [e1].[IntA], [e1].[IntB], [e1].[IntC], [e1].[NullableBoolA], [e1].[NullableBoolB], [e1].[NullableBoolC], [e1].[NullableIntA], [e1].[NullableIntB], [e1].[NullableIntC], [e1].[NullableStringA], [e1].[NullableStringB], [e1].[NullableStringC], [e1].[StringA], [e1].[StringB], [e1].[StringC], [e2].[Id], [e2].[BoolA], [e2].[BoolB], [e2].[BoolC], [e2].[IntA], [e2].[IntB], [e2].[IntC], [e2].[NullableBoolA], [e2].[NullableBoolB], [e2].[NullableBoolC], [e2].[NullableIntA], [e2].[NullableIntB], [e2].[NullableIntC], [e2].[NullableStringA], [e2].[NullableStringB], [e2].[NullableStringC], [e2].[StringA], [e2].[StringB], [e2].[StringC] +FROM [Entities1] AS [e1] +INNER JOIN [Entities2] AS [e2] ON CASE + WHEN [e1].[NullableStringA] <> N'Foo' + THEN CAST(1 AS bit) ELSE CAST(0 AS bit) +END = CASE + WHEN [e2].[NullableBoolB] <> CAST(1 AS bit) + THEN CAST(1 AS bit) ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Where_conditional_search_condition_in_result(bool async) + { + await base.Where_conditional_search_condition_in_result(async); + + AssertSql( + """ +@list='["Foo","Bar"]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] IN ( + SELECT [l].[value] + FROM OPENJSON(@list) WITH ([value] nvarchar(max) '$') AS [l] +) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] LIKE N'B%' +"""); + } + + public override async Task Where_nested_conditional_search_condition_in_result(bool async) + { + await base.Where_nested_conditional_search_condition_in_result(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +"""); + } + + public override void Where_equal_using_relational_null_semantics() + { + base.Where_equal_using_relational_null_semantics(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] +"""); + } + + public override void Where_contains_on_parameter_array_with_relational_null_semantics() + { + base.Where_contains_on_parameter_array_with_relational_null_semantics(); + + AssertSql( + """ +@names='["Foo","Bar"]' (Size = 4000) + +SELECT [e].[NullableStringA] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [n].[value] + FROM OPENJSON(@names) WITH ([value] nvarchar(max) '$') AS [n] +) +"""); + } + + public override void Where_contains_on_parameter_empty_array_with_relational_null_semantics() + { + base.Where_contains_on_parameter_empty_array_with_relational_null_semantics(); + + AssertSql( + """ +@names='[]' (Size = 4000) + +SELECT [e].[NullableStringA] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [n].[value] + FROM OPENJSON(@names) WITH ([value] nvarchar(max) '$') AS [n] +) +"""); + } + + public override void Where_contains_on_parameter_array_with_just_null_with_relational_null_semantics() + { + base.Where_contains_on_parameter_array_with_just_null_with_relational_null_semantics(); + + AssertSql( + """ +@names='[null]' (Size = 4000) + +SELECT [e].[NullableStringA] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [n].[value] + FROM OPENJSON(@names) WITH ([value] nvarchar(max) '$') AS [n] +) +"""); + } + + public override async Task Where_nullable_bool(bool async) + { + await base.Where_nullable_bool(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = CAST(1 AS bit) +"""); + } + + public override async Task Where_nullable_bool_equal_with_constant(bool async) + { + await base.Where_nullable_bool_equal_with_constant(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = CAST(1 AS bit) +"""); + } + + public override async Task Where_nullable_bool_with_null_check(bool async) + { + await base.Where_nullable_bool_with_null_check(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] IS NOT NULL AND [e].[NullableBoolA] = CAST(1 AS bit) +"""); + } + + public override void Where_equal_using_relational_null_semantics_with_parameter() + { + base.Where_equal_using_relational_null_semantics_with_parameter(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] IS NULL +"""); + } + + public override void Where_equal_using_relational_null_semantics_complex_with_parameter() + { + base.Where_equal_using_relational_null_semantics_complex_with_parameter(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] +"""); + } + + public override void Where_not_equal_using_relational_null_semantics() + { + base.Where_not_equal_using_relational_null_semantics(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] +"""); + } + + public override void Where_not_equal_using_relational_null_semantics_with_parameter() + { + base.Where_not_equal_using_relational_null_semantics_with_parameter(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] IS NOT NULL +"""); + } + + public override void Where_not_equal_using_relational_null_semantics_complex_with_parameter() + { + base.Where_not_equal_using_relational_null_semantics_complex_with_parameter(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] +"""); + } + + public override async Task Where_comparison_null_constant_and_null_parameter(bool async) + { + await base.Where_comparison_null_constant_and_null_parameter(async); + + AssertSql( + """ +@p='True' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +""", + // + """ +@p='False' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +"""); + } + + public override async Task Where_comparison_null_constant_and_nonnull_parameter(bool async) + { + await base.Where_comparison_null_constant_and_nonnull_parameter(async); + + AssertSql( + """ +@p='False' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +""", + // + """ +@p='True' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +"""); + } + + public override async Task Where_comparison_nonnull_constant_and_null_parameter(bool async) + { + await base.Where_comparison_nonnull_constant_and_null_parameter(async); + + AssertSql( + """ +@p='False' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +""", + // + """ +@p='True' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +"""); + } + + public override async Task Where_comparison_null_semantics_optimization_works_with_complex_predicates(bool async) + { + await base.Where_comparison_null_semantics_optimization_works_with_complex_predicates(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NULL +"""); + } + + public override void Switching_null_semantics_produces_different_cache_entry() + { + base.Switching_null_semantics_produces_different_cache_entry(); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] +"""); + } + + public override void Switching_parameter_value_to_null_produces_different_cache_entry() + { + base.Switching_parameter_value_to_null_produces_different_cache_entry(); + + AssertSql( + """ +@p='True' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +""", + // + """ +@p='False' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE @p = CAST(1 AS bit) +"""); + } + + public override void From_sql_composed_with_relational_null_comparison() + { + base.From_sql_composed_with_relational_null_comparison(); + + AssertSql( + """ +SELECT [m].[Id], [m].[BoolA], [m].[BoolB], [m].[BoolC], [m].[IntA], [m].[IntB], [m].[IntC], [m].[NullableBoolA], [m].[NullableBoolB], [m].[NullableBoolC], [m].[NullableIntA], [m].[NullableIntB], [m].[NullableIntC], [m].[NullableStringA], [m].[NullableStringB], [m].[NullableStringC], [m].[StringA], [m].[StringB], [m].[StringC] +FROM ( + SELECT * FROM "Entities1" +) AS [m] +WHERE [m].[StringA] = [m].[StringB] +"""); + } + + public override async Task Projecting_nullable_bool_with_coalesce(bool async) + { + await base.Projecting_nullable_bool_with_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id], COALESCE([e].[NullableBoolA], CAST(0 AS bit)) AS [Coalesce] +FROM [Entities1] AS [e] +"""); + } + + public override async Task Projecting_nullable_bool_with_coalesce_nested(bool async) + { + await base.Projecting_nullable_bool_with_coalesce_nested(async); + + AssertSql( + """ +SELECT [e].[Id], COALESCE([e].[NullableBoolA], [e].[NullableBoolB], CAST(0 AS bit)) AS [Coalesce] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id], COALESCE([e].[NullableBoolA], [e].[NullableBoolB], CAST(0 AS bit)) AS [Coalesce] +FROM [Entities1] AS [e] +"""); + } + + public override async Task Null_semantics_applied_when_comparing_function_with_nullable_argument_to_a_nullable_column(bool async) + { + await base.Null_semantics_applied_when_comparing_function_with_nullable_argument_to_a_nullable_column(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 = [e].[NullableIntA] OR ([e].[NullableStringA] IS NULL AND [e].[NullableIntA] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CAST(CHARINDEX(N'ar', [e].[NullableStringA]) AS int) - 1 = [e].[NullableIntA] OR ([e].[NullableStringA] IS NULL AND [e].[NullableIntA] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 <> [e].[NullableIntB] OR [e].[NullableStringA] IS NULL OR [e].[NullableIntB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) +"""); + } + + public override async Task Where_IndexOf_empty(bool async) + { + await base.Where_IndexOf_empty(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableStringA] IS NOT NULL THEN 0 +END = [e].[NullableIntA] OR (CASE + WHEN [e].[NullableStringA] IS NOT NULL THEN 0 +END IS NULL AND [e].[NullableIntA] IS NULL) +"""); + } + + public override async Task Select_IndexOf(bool async) + { + await base.Select_IndexOf(async); + + AssertSql( + """ +SELECT CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 +FROM [Entities1] AS [e] +ORDER BY [e].[Id] +"""); + } + + public override async Task Null_semantics_applied_when_comparing_two_functions_with_nullable_arguments(bool async) + { + await base.Null_semantics_applied_when_comparing_two_functions_with_nullable_arguments(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 = CAST(CHARINDEX(N'ar', [e].[NullableStringB]) AS int) - 1 OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 <> CAST(CHARINDEX(N'ar', [e].[NullableStringB]) AS int) - 1 OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (CAST(CHARINDEX(N'oo', [e].[NullableStringA]) AS int) - 1 <> CAST(CHARINDEX(N'ar', [e].[NullableStringA]) AS int) - 1 OR [e].[NullableStringA] IS NULL) AND [e].[NullableStringA] IS NOT NULL +"""); + } + + public override async Task Null_semantics_applied_when_comparing_two_functions_with_multiple_nullable_arguments(bool async) + { + await base.Null_semantics_applied_when_comparing_two_functions_with_multiple_nullable_arguments(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE REPLACE([e].[NullableStringA], [e].[NullableStringB], [e].[NullableStringC]) = [e].[NullableStringA] OR (([e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL OR [e].[NullableStringC] IS NULL) AND [e].[NullableStringA] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (REPLACE([e].[NullableStringA], [e].[NullableStringB], [e].[NullableStringC]) <> [e].[NullableStringA] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL OR [e].[NullableStringC] IS NULL OR [e].[NullableStringA] IS NULL) AND (([e].[NullableStringA] IS NOT NULL AND [e].[NullableStringB] IS NOT NULL AND [e].[NullableStringC] IS NOT NULL) OR [e].[NullableStringA] IS NOT NULL) +"""); + } + + public override async Task Null_semantics_coalesce(bool async) + { + await base.Null_semantics_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = COALESCE([e].[NullableBoolB], [e].[BoolC]) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableBoolA] = COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +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) +"""); + } + + public override async Task Null_semantics_conditional(bool async) + { + await base.Null_semantics_conditional(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CASE + WHEN [e].[BoolB] = CAST(1 AS bit) THEN [e].[NullableBoolB] + ELSE [e].[NullableBoolC] +END +""", + // + """ +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] + ELSE [e].[BoolC] +END = [e].[BoolA] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE 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] + 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) +""", + // + """ +SELECT CASE + WHEN CASE + WHEN [e].[BoolA] = CAST(1 AS bit) THEN [e].[NullableIntA] + ELSE [e].[IntB] + END > [e].[IntC] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Entities1] AS [e] +"""); + } + + public override async Task Null_semantics_function(bool async) + { + await base.Null_semantics_function(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (SUBSTRING([e].[NullableStringA], 0 + 1, [e].[IntA]) <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) +"""); + } + + public override async Task Null_semantics_join_with_composite_key(bool async) + { + await base.Null_semantics_join_with_composite_key(async); + + AssertSql( + """ +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], [e0].[Id], [e0].[BoolA], [e0].[BoolB], [e0].[BoolC], [e0].[IntA], [e0].[IntB], [e0].[IntC], [e0].[NullableBoolA], [e0].[NullableBoolB], [e0].[NullableBoolC], [e0].[NullableIntA], [e0].[NullableIntB], [e0].[NullableIntC], [e0].[NullableStringA], [e0].[NullableStringB], [e0].[NullableStringC], [e0].[StringA], [e0].[StringB], [e0].[StringC] +FROM [Entities1] AS [e] +INNER JOIN [Entities2] AS [e0] ON ([e].[NullableStringA] = [e0].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e0].[NullableStringB] IS NULL)) AND CASE + WHEN ([e].[NullableStringB] <> [e].[NullableStringC] OR [e].[NullableStringB] IS NULL OR [e].[NullableStringC] IS NULL) AND ([e].[NullableStringB] IS NOT NULL OR [e].[NullableStringC] IS NOT NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = COALESCE([e0].[NullableBoolA], [e0].[BoolC]) +"""); + } + + public override async Task Null_semantics_contains(bool async) + { + await base.Null_semantics_contains(async); + + AssertSql( + """ +@ids='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] +) OR [e].[NullableIntA] IS NULL +""", + // + """ +@ids2_without_nulls='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2_without_nulls) AS [i] +) OR [e].[NullableIntA] IS NULL +""", + // + """ +@ids2_without_nulls='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2_without_nulls) AS [i] +) AND [e].[NullableIntA] IS NOT NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN (1, 2) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN (1, 2) OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN (1, 2) OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN (1, 2) AND [e].[NullableIntA] IS NOT NULL +"""); + } + + public override async Task Null_semantics_contains_array_with_no_values(bool async) + { + await base.Null_semantics_contains_array_with_no_values(async); + + AssertSql( + """ +@ids='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] +) OR [e].[NullableIntA] IS NULL +""", + // + """ +@ids2_without_nulls='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2_without_nulls) AS [i] +) OR [e].[NullableIntA] IS NULL +""", + // + """ +@ids2_without_nulls='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2_without_nulls) AS [i] +) AND [e].[NullableIntA] IS NOT NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE 0 = 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL +"""); + } + + public override async Task Null_semantics_contains_non_nullable_item_with_non_nullable_subquery(bool async) + { + await base.Null_semantics_contains_non_nullable_item_with_non_nullable_subquery(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] IN ( + SELECT [e0].[StringA] + FROM [Entities2] AS [e0] +) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] NOT IN ( + SELECT [e0].[StringA] + FROM [Entities2] AS [e0] +) +"""); + } + + public override async Task Null_semantics_contains_nullable_item_with_non_nullable_subquery(bool async) + { + await base.Null_semantics_contains_nullable_item_with_non_nullable_subquery(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IN ( + SELECT [e0].[StringA] + FROM [Entities2] AS [e0] +) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT IN ( + SELECT [e0].[StringA] + FROM [Entities2] AS [e0] +) OR [e].[NullableStringA] IS NULL +"""); + } + + public override async Task Null_semantics_contains_non_nullable_item_with_nullable_subquery(bool async) + { + await base.Null_semantics_contains_non_nullable_item_with_nullable_subquery(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] IN ( + SELECT [e0].[NullableStringA] + FROM [Entities2] AS [e0] +) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE NOT EXISTS ( + SELECT 1 + FROM [Entities2] AS [e0] + WHERE [e0].[NullableStringA] = [e].[StringA]) +"""); + } + + public override async Task Null_semantics_contains_nullable_item_with_nullable_subquery(bool async) + { + await base.Null_semantics_contains_nullable_item_with_nullable_subquery(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE EXISTS ( + SELECT 1 + FROM [Entities2] AS [e0] + WHERE [e0].[NullableStringA] = [e].[NullableStringB] OR ([e0].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL)) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE NOT EXISTS ( + SELECT 1 + FROM [Entities2] AS [e0] + WHERE [e0].[NullableStringA] = [e].[NullableStringB] OR ([e0].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL)) +"""); + } + + #region Contains with inline collection + + public override async Task Null_semantics_contains_with_non_nullable_item_and_inline_non_nullable_values(bool async) + { + await base.Null_semantics_contains_with_non_nullable_item_and_inline_non_nullable_values(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN (1, 2) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN (1, 2) +"""); + } + + public override async Task Null_semantics_contains_with_non_nullable_item_and_inline_values_with_null(bool async) + { + await base.Null_semantics_contains_with_non_nullable_item_and_inline_values_with_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN (1, 2) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN (1, 2) +"""); + } + + public override async Task Null_semantics_contains_with_non_nullable_item_and_inline_values_with_nullable_column(bool async) + { + await base.Null_semantics_contains_with_non_nullable_item_and_inline_values_with_nullable_column(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN (1, 2, [e].[NullableIntB]) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN (1, 2) AND ([e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL) +"""); + } + + public override async Task Null_semantics_contains_with_non_nullable_item_and_inline_values_with_nullable_column_and_null(bool async) + { + await base.Null_semantics_contains_with_non_nullable_item_and_inline_values_with_nullable_column_and_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN (1, 2, [e].[NullableIntB]) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN (1, 2) AND ([e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL) +"""); + } + + public override async Task Null_semantics_contains_with_nullable_item_and_inline_non_nullable_values(bool async) + { + await base.Null_semantics_contains_with_nullable_item_and_inline_non_nullable_values(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN (1, 2) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN (1, 2) OR [e].[NullableIntA] IS NULL +"""); + } + + public override async Task Null_semantics_contains_with_nullable_item_and_inline_values_with_null(bool async) + { + await base.Null_semantics_contains_with_nullable_item_and_inline_values_with_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN (1, 2) OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN (1, 2) AND [e].[NullableIntA] IS NOT NULL +"""); + } + + public override async Task Null_semantics_contains_with_nullable_item_and_inline_values_with_nullable_column(bool async) + { + await base.Null_semantics_contains_with_nullable_item_and_inline_values_with_nullable_column(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableIntA] IN (1, 2) AND [e].[NullableIntA] IS NOT NULL) OR [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableIntA] NOT IN (1, 2) OR [e].[NullableIntA] IS NULL) AND ([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) +"""); + } + + public override async Task Null_semantics_contains_with_nullable_item_and_values_with_nullable_column_and_null(bool async) + { + await base.Null_semantics_contains_with_nullable_item_and_values_with_nullable_column_and_null(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IN (1, 2) OR [e].[NullableIntA] IS NULL OR [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] NOT IN (1, 2) AND [e].[NullableIntA] IS NOT NULL AND ([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) +"""); + } + + public override async Task Null_semantics_contains_with_non_nullable_item_and_one_value(bool async) + { + await base.Null_semantics_contains_with_non_nullable_item_and_one_value(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE 0 = 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] = [e].[NullableIntB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL +"""); + } + + public override async Task Null_semantics_contains_with_nullable_item_and_one_value(bool async) + { + await base.Null_semantics_contains_with_nullable_item_and_one_value(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] <> 1 OR [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] = [e].[NullableIntB] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([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) +"""); + } + + #endregion Contains with inline collection + + public override async Task Null_semantics_contains_non_nullable_item_with_values(bool async) + { + await base.Null_semantics_contains_non_nullable_item_with_values(async); + + AssertSql( + """ +@ids='[1,2,null]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids_without_nulls='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids_without_nulls) AS [i] +) +""", + // + """ +@ids2='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids2='[1,2]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids2) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids3='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids3) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids3='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids3) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids4='[null]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] IN ( + SELECT [i].[value] + FROM OPENJSON(@ids4) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ids4_without_nulls='[]' (Size = 4000) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ids4_without_nulls) AS [i] +) +"""); + } + + public override async Task Null_semantics_with_null_check_simple(bool async) + { + await base.Null_semantics_with_null_check_simple(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND [e].[NullableIntA] = [e].[NullableIntB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND ([e].[NullableIntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND [e].[NullableIntA] = [e].[IntC] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND [e].[NullableIntB] IS NOT NULL AND [e].[NullableIntA] = [e].[NullableIntB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND [e].[NullableIntB] IS NOT NULL AND [e].[NullableIntA] <> [e].[NullableIntB] +"""); + } + + public override async Task Null_semantics_with_null_check_complex(bool async) + { + await base.Null_semantics_with_null_check_complex(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND ([e].[NullableIntC] <> [e].[NullableIntA] OR [e].[NullableIntC] IS NULL OR ([e].[NullableIntB] IS NOT NULL AND [e].[NullableIntA] <> [e].[NullableIntB])) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL AND ([e].[NullableIntC] <> [e].[NullableIntA] OR [e].[NullableIntC] IS NULL OR [e].[NullableIntA] <> [e].[NullableIntB] OR [e].[NullableIntB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) AND ([e].[NullableIntA] = [e].[NullableIntC] OR ([e].[NullableIntA] IS NULL AND [e].[NullableIntC] IS NULL)) +"""); + } + + public override async Task Null_semantics_with_null_check_complex2(bool async) + { + await base.Null_semantics_with_null_check_complex2(async); + + AssertSql( + """ +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 +""", + // + """ +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 +"""); + } + + public override async Task IsNull_on_complex_expression(bool async) + { + await base.IsNull_on_complex_expression(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NULL OR [e].[NullableIntB] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL +"""); + } + + public override async Task Coalesce_not_equal(bool async) + { + await base.Coalesce_not_equal(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE COALESCE([e].[NullableIntA], 0) <> 0 +"""); + } + + public override async Task Negated_order_comparison_on_non_nullable_arguments_gets_optimized(bool async) + { + await base.Negated_order_comparison_on_non_nullable_arguments_gets_optimized(async); + + AssertSql( + """ +@i='1' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] <= @i +""", + // + """ +@i='1' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] < @i +""", + // + """ +@i='1' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] >= @i +""", + // + """ +@i='1' + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[IntA] > @i +"""); + } + + public override async Task Negated_order_comparison_on_nullable_arguments_doesnt_get_optimized(bool async) + { + await base.Negated_order_comparison_on_nullable_arguments_doesnt_get_optimized(async); + + AssertSql( + """ +@i='1' (Nullable = true) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableIntA] > @i THEN CAST(0 AS bit) + ELSE CAST(1 AS bit) +END = CAST(1 AS bit) +""", + // + """ +@i='1' (Nullable = true) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableIntA] >= @i THEN CAST(0 AS bit) + ELSE CAST(1 AS bit) +END = CAST(1 AS bit) +""", + // + """ +@i='1' (Nullable = true) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableIntA] < @i THEN CAST(0 AS bit) + ELSE CAST(1 AS bit) +END = CAST(1 AS bit) +""", + // + """ +@i='1' (Nullable = true) + +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE CASE + WHEN [e].[NullableIntA] <= @i THEN CAST(0 AS bit) + ELSE CAST(1 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Nullable_column_info_propagates_inside_binary_AndAlso(bool async) + { + await base.Nullable_column_info_propagates_inside_binary_AndAlso(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] IS NOT NULL AND [e].[NullableStringB] IS NOT NULL AND [e].[NullableStringA] <> [e].[NullableStringB] +"""); + } + + public override async Task Nullable_column_info_doesnt_propagate_inside_binary_OrElse(bool async) + { + await base.Nullable_column_info_doesnt_propagate_inside_binary_OrElse(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) AND ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) +"""); + } + + public override async Task Nullable_column_info_propagates_inside_binary_OrElse_when_info_is_duplicated(bool async) + { + await base.Nullable_column_info_propagates_inside_binary_OrElse_when_info_is_duplicated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (([e].[NullableStringA] IS NOT NULL AND [e].[NullableStringB] IS NOT NULL) OR [e].[NullableStringA] IS NOT NULL) AND ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringB] IS NULL) +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE (([e].[NullableStringA] IS NOT NULL AND [e].[NullableStringB] IS NOT NULL) OR ([e].[NullableStringB] IS NOT NULL AND [e].[NullableStringA] IS NOT NULL)) AND [e].[NullableStringA] <> [e].[NullableStringB] +"""); + } + + public override async Task Nullable_column_info_propagates_inside_conditional(bool async) + { + await base.Nullable_column_info_propagates_inside_conditional(async); + + AssertSql( + """ +SELECT CASE + WHEN [e].[NullableStringA] IS NOT NULL THEN CASE + WHEN [e].[NullableStringA] <> [e].[StringA] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END + ELSE [e].[BoolA] +END +FROM [Entities1] AS [e] +"""); + } + + public override async Task Nullable_column_info_doesnt_propagate_between_projections(bool async) + { + await base.Nullable_column_info_doesnt_propagate_between_projections(async); + + AssertSql( + """ +SELECT CASE + WHEN [e].[NullableStringA] IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [Foo], CASE + WHEN [e].[NullableStringA] <> [e].[StringA] OR [e].[NullableStringA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [Bar] +FROM [Entities1] AS [e] +"""); + } + + public override async Task Nullable_column_info_doesnt_propagate_between_different_parts_of_select(bool async) + { + await base.Nullable_column_info_doesnt_propagate_between_different_parts_of_select(async); + + AssertSql( + """ +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) +"""); + } + + public override async Task Nullable_column_info_propagation_complex(bool async) + { + await base.Nullable_column_info_propagation_complex(async); + + AssertSql( + """ +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) +"""); + } + + public override async Task Empty_subquery_with_contains_returns_false(bool async) + { + await base.Empty_subquery_with_contains_returns_false(async); + + AssertSql( + """ +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 0 = 1 +"""); + } + + public override async Task Empty_subquery_with_contains_negated_returns_true(bool async) + { + await base.Empty_subquery_with_contains_negated_returns_true(async); + + AssertSql( + """ +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] +"""); + } + + public override async Task Nullable_string_FirstOrDefault_compared_to_nullable_string_LastOrDefault(bool async) + { + await base.Nullable_string_FirstOrDefault_compared_to_nullable_string_LastOrDefault(async); + + AssertSql( + """ +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 SUBSTRING([e].[NullableStringA], 1, 1) = SUBSTRING([e].[NullableStringB], LEN([e].[NullableStringB]), 1) OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) +"""); + } + + public override async Task Null_semantics_applied_to_CompareTo_equality(bool async) + { + await base.Null_semantics_applied_to_CompareTo_equality(async); + + AssertSql( + """ +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] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] 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].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] 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].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] 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 ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) +"""); + } + + public override async Task Nested_CompareTo_optimized(bool async) + { + await base.Nested_CompareTo_optimized(async); + + AssertSql( + """ +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] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] 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].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] 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].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] 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 ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) +"""); + } + + public override async Task False_compared_to_negated_is_null(bool async) + { + await base.False_compared_to_negated_is_null(async); + + AssertSql( + """ +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 NULL +"""); + } + + public override async Task CaseWhen_equal_to_second_filter(bool async) + { + await base.CaseWhen_equal_to_second_filter(async); + + AssertSql( + """ +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 CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 +END = 2 +"""); + } + + public override async Task CaseWhen_equal_to_first_or_third_filter(bool async) + { + await base.CaseWhen_equal_to_first_or_third_filter(async); + + AssertSql( + """ +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 CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 +END = 3 +"""); + } + + public override async Task CaseWhen_equal_to_second_select(bool async) + { + await base.CaseWhen_equal_to_second_select(async); + + AssertSql( + """ +SELECT CASE + WHEN CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 + END = 2 AND CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 + END IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Entities1] AS [e] +ORDER BY [e].[Id] +"""); + } + + public override async Task CaseWhen_equal_to_first_or_third_select(bool async) + { + await base.CaseWhen_equal_to_first_or_third_select(async); + + AssertSql( + """ +SELECT CASE + WHEN CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 + END = 3 AND CASE + WHEN [e].[StringA] = N'Foo' THEN 3 + WHEN [e].[StringB] = N'Foo' THEN 2 + WHEN [e].[StringC] = N'Foo' THEN 3 + END IS NOT NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Entities1] AS [e] +ORDER BY [e].[Id] +"""); + } + + public override async Task CaseOpWhen_projection(bool async) + { + await base.CaseOpWhen_projection(async); + + AssertSql( + """ +SELECT CASE CASE + WHEN [e].[StringA] = N'Foo' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END + WHEN CAST(1 AS bit) THEN 3 + WHEN CAST(0 AS bit) THEN 2 +END +FROM [Entities1] AS [e] +ORDER BY [e].[Id] +"""); + } + + public override async Task CaseOpWhen_predicate(bool async) + { + await base.CaseOpWhen_predicate(async); + + AssertSql( + """ +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 CASE CASE + WHEN [e].[StringA] = N'Foo' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END + WHEN CAST(1 AS bit) THEN 3 + WHEN CAST(0 AS bit) THEN 2 +END = 2 +"""); + } + + public override async Task Multiple_non_equality_comparisons_with_null_in_the_middle(bool async) + { + await base.Multiple_non_equality_comparisons_with_null_in_the_middle(async); + + AssertSql( + """ +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].[NullableIntA] NOT IN (1, 2) AND [e].[NullableIntA] IS NOT NULL +"""); + } + + public override async Task Multiple_non_equality_comparisons_including_null_comparison_work_for_relational_null_semantics( + bool async) + { + await base.Multiple_non_equality_comparisons_including_null_comparison_work_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] <> 1 AND [e].[NullableIntA] IS NOT NULL +"""); + } + + public override async Task Multiple_non_equality_comparisons_without_null_comparison_work_for_relational_null_semantics(bool async) + { + await base.Multiple_non_equality_comparisons_without_null_comparison_work_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] NOT IN (1, 2) +"""); + } + + public override async Task Multiple_equality_comparisons_including_null_comparison_work_for_relational_null_semantics(bool async) + { + await base.Multiple_equality_comparisons_including_null_comparison_work_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] = 1 OR [e].[NullableIntA] IS NULL +"""); + } + + public override async Task Multiple_contains_calls_get_combined_into_one_for_relational_null_semantics(bool async) + { + await base.Multiple_contains_calls_get_combined_into_one_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] IN (1, NULL, 2, 3) +"""); + } + + public override async Task Multiple_negated_contains_calls_get_combined_into_one_for_relational_null_semantics(bool async) + { + await base.Multiple_negated_contains_calls_get_combined_into_one_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] NOT IN (1, NULL, 2, 3) +"""); + } + + public override async Task Contains_with_comparison_dont_get_combined_for_relational_null_semantics(bool async) + { + await base.Contains_with_comparison_dont_get_combined_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] IN (1, 2) OR [e].[NullableIntA] IS NULL +"""); + } + + public override async Task Negated_contains_with_comparison_dont_get_combined_for_relational_null_semantics(bool async) + { + await base.Negated_contains_with_comparison_dont_get_combined_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] IS NOT NULL AND [e].[NullableIntA] NOT IN (1, 2) +"""); + } + + public override async Task Negated_contains_with_comparison_without_null_get_combined_for_relational_null_semantics(bool async) + { + await base.Negated_contains_with_comparison_without_null_get_combined_for_relational_null_semantics(async); + + AssertSql( + """ +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].[NullableIntA] NOT IN (3, 1, 2) +"""); + } + + public override async Task Bool_equal_nullable_bool_HasValue(bool async) + { + await base.Bool_equal_nullable_bool_HasValue(async); + + AssertSql( + """ +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].[NullableBoolA] IS NOT NULL +""", + // + """ +@prm='False' + +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) + ELSE CAST(0 AS bit) +END +""", + // + """ +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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Bool_equal_nullable_bool_compared_to_null(bool async) + { + await base.Bool_equal_nullable_bool_compared_to_null(async); + + AssertSql( + """ +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].[NullableBoolA] IS NULL +""", + // + """ +@prm='False' + +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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Bool_not_equal_nullable_bool_HasValue(bool async) + { + await base.Bool_not_equal_nullable_bool_HasValue(async); + + AssertSql( + """ +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].[NullableBoolA] IS NULL +""", + // + """ +@prm='False' + +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Bool_not_equal_nullable_int_HasValue(bool async) + { + await base.Bool_not_equal_nullable_int_HasValue(async); + + AssertSql( + """ +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].[NullableIntA] IS NULL +""", + // + """ +@prm='False' + +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +""", + // + """ +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Bool_not_equal_nullable_bool_compared_to_null(bool async) + { + await base.Bool_not_equal_nullable_bool_compared_to_null(async); + + AssertSql( + """ +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].[NullableBoolA] IS NOT NULL +""", + // + """ +@prm='False' + +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Bool_logical_operation_with_nullable_bool_HasValue(bool async) + { + await base.Bool_logical_operation_with_nullable_bool_HasValue(async); + + AssertSql( + """ +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] +""", + // + """ +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 0 = 1 +""", + // + """ +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] = CAST(1 AS bit) OR [e].[NullableBoolA] IS NOT NULL +"""); + } + + public override async Task Comparison_compared_to_null_check_on_bool(bool async) + { + await base.Comparison_compared_to_null_check_on_bool(async); + + AssertSql( + """ +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 NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +""", + // + """ +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) + ELSE CAST(0 AS bit) +END +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_simple(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_simple(async); + + AssertSql( + """ +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 AND [e].[NullableStringA] = N'Foo' +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_negative(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_negative(async); + + AssertSql( + """ +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' +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_nested(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_nested(async); + + AssertSql( + """ +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 NULL OR [e].[NullableStringB] IS NULL OR [e].[NullableStringA] <> [e].[NullableStringB] +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_intersection(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_intersection(async); + + AssertSql( + """ +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 NULL AND ([e].[StringA] = N'Foo' OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL)) OR [e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringB] IS NULL +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional(async); + + // issue #25977 + AssertSql( + """ +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 CASE + WHEN [e].[NullableStringA] IS NULL THEN CASE + WHEN ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END + WHEN ([e].[NullableStringA] <> [e].[NullableStringC] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringC] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringC] IS NOT NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_multiple(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_multiple(async); + + // issue #25977 + AssertSql( + """ +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 CASE + WHEN [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL THEN CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END + WHEN ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_negative(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_negative(async); + + AssertSql( + """ +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 CASE + WHEN ([e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND [e].[NullableBoolC] IS NULL THEN CASE + WHEN [e].[NullableStringA] = [e].[NullableStringB] OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END + WHEN ([e].[NullableStringA] <> [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_with_setup(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_with_setup(async); + + // issue #25977 + AssertSql( + """ +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].[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) + ELSE CAST(0 AS bit) + END + 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) +"""); + } + + public override async Task Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_nested(bool async) + { + await base.Is_null_on_column_followed_by_OrElse_optimizes_nullability_conditional_nested(async); + + // issue #25977 + AssertSql( + """ +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 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) + 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) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Sum_function_is_always_considered_non_nullable(bool async) + { + await base.Sum_function_is_always_considered_non_nullable(async); + + AssertSql( + """ +SELECT [e].[NullableIntA] AS [Key], CASE + WHEN COALESCE(SUM([e].[IntA]), 0) <> [e].[NullableIntA] OR [e].[NullableIntA] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END AS [Sum] +FROM [Entities1] AS [e] +GROUP BY [e].[NullableIntA] +"""); + } + + public override async Task Nullability_is_computed_correctly_for_chained_coalesce(bool async) + { + await base.Nullability_is_computed_correctly_for_chained_coalesce(async); + + AssertSql( + """ +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 COALESCE([e].[NullableIntA], [e].[NullableIntB], [e].[IntC]) <> [e].[NullableIntC] OR [e].[NullableIntC] IS NULL +"""); + } + + public override async Task Nullability_check_is_computed_correctly_for_chained_coalesce(bool async) + { + await base.Nullability_check_is_computed_correctly_for_chained_coalesce(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL AND [e].[NullableIntC] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL OR [e].[NullableIntC] IS NOT NULL +"""); + } + + public override async Task Coalesce_on_self_gets_simplified(bool async) + { + await base.Coalesce_on_self_gets_simplified(async); + + AssertSql( + """ +SELECT [e].[NullableStringA] +FROM [Entities1] AS [e] +"""); + } + + public override async Task Coalesce_deeply_nested(bool async) + { + await base.Coalesce_deeply_nested(async); + + AssertSql( + """ +SELECT COALESCE([e].[NullableIntA], [e].[NullableIntB], [e0].[NullableIntC], [e0].[NullableIntB], [e].[NullableIntC], [e0].[NullableIntA]) +FROM [Entities1] AS [e] +INNER JOIN [Entities2] AS [e0] ON [e].[Id] = [e0].[Id] +"""); + } + + public override async Task Like(bool async) + { + await base.Like(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] LIKE [e].[StringB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] LIKE [e].[NullableStringB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] LIKE [e].[StringB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] LIKE [e].[NullableStringB] +"""); + } + + public override async Task Like_negated(bool async) + { + await base.Like_negated(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] NOT LIKE [e].[StringB] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] NOT LIKE [e].[NullableStringB] OR [e].[NullableStringB] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT LIKE [e].[StringB] OR [e].[NullableStringA] IS NULL +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[NullableStringA] NOT LIKE [e].[NullableStringB] OR [e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL +"""); + } + + public override async Task Like_with_escape_char(bool async) + { + await base.Like_with_escape_char(async); + + AssertSql( + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] LIKE [e].[StringB] ESCAPE N'\' +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[StringA] NOT LIKE [e].[StringB] ESCAPE N'\' +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE 0 = 1 +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +"""); + } + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); + + protected override NullSemanticsContext CreateContext(bool useRelationalNulls = false) + { + var options = new DbContextOptionsBuilder(Fixture.CreateOptions()); + if (useRelationalNulls) + { + new SqlServerDbContextOptionsBuilder(options).UseRelationalNulls(); + } + + var context = new NullSemanticsContext(options.Options); + + context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + + return context; + } + + protected override void ClearLog() + => Fixture.TestSqlLoggerFactory.Clear(); + + public class NullSemanticsQueryOldSqlServerFixture : NullSemanticsQuerySqlServerFixture + { + // Use a different store name to prevent concurrency issues with the non-old PrimitiveCollectionsQuerySqlServerTest + protected override string StoreName + => "Old" + base.StoreName; + + // Compatibility level below 160 (SQL Server 2022) doesn't support IS [NOT] DISTINCT FROM + public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => base.AddOptions(builder).UseSqlServer(o => o.UseCompatibilityLevel(150)); + } +} From 3a0ed272b6338f6a0b004ae42f8903b674e4612f Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sat, 13 Jul 2024 19:58:32 +0200 Subject: [PATCH 4/8] Use primary constructors for some SqlServer classes --- .../SqlServerParameterBasedSqlProcessor.cs | 20 +++++-------------- ...ServerParameterBasedSqlProcessorFactory.cs | 14 ++----------- .../SqlServerSqlNullabilityProcessor.cs | 18 ++++------------- 3 files changed, 11 insertions(+), 41 deletions(-) diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs index 94c15ba6c68..f23d3c50e6d 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -9,21 +9,11 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerParameterBasedSqlProcessor : RelationalParameterBasedSqlProcessor +public class SqlServerParameterBasedSqlProcessor( + RelationalParameterBasedSqlProcessorDependencies dependencies, + RelationalParameterBasedSqlProcessorParameters parameters) + : RelationalParameterBasedSqlProcessor(dependencies, parameters) { - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public SqlServerParameterBasedSqlProcessor( - RelationalParameterBasedSqlProcessorDependencies dependencies, - RelationalParameterBasedSqlProcessorParameters parameters) - : base(dependencies, parameters) - { - } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs index 9d60b17dba7..6cf2826794b 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs @@ -9,22 +9,12 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerParameterBasedSqlProcessorFactory : IRelationalParameterBasedSqlProcessorFactory +public class SqlServerParameterBasedSqlProcessorFactory(RelationalParameterBasedSqlProcessorDependencies dependencies) : IRelationalParameterBasedSqlProcessorFactory { - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public SqlServerParameterBasedSqlProcessorFactory( - RelationalParameterBasedSqlProcessorDependencies dependencies) - => Dependencies = dependencies; - /// /// Relational provider-specific dependencies for this service. /// - protected virtual RelationalParameterBasedSqlProcessorDependencies Dependencies { get; } + protected virtual RelationalParameterBasedSqlProcessorDependencies Dependencies { get; } = dependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs index a3fb56ea225..be0ac47926e 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs @@ -12,21 +12,11 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerSqlNullabilityProcessor : SqlNullabilityProcessor +public class SqlServerSqlNullabilityProcessor( + RelationalParameterBasedSqlProcessorDependencies dependencies, + RelationalParameterBasedSqlProcessorParameters parameters) + : SqlNullabilityProcessor(dependencies, parameters) { - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public SqlServerSqlNullabilityProcessor( - RelationalParameterBasedSqlProcessorDependencies dependencies, - RelationalParameterBasedSqlProcessorParameters parameters) - : base(dependencies, parameters) - { - } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in From 64674b31f274f1add1019b0d86cb478bbad36852 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sat, 13 Jul 2024 19:58:32 +0200 Subject: [PATCH 5/8] Add `IS DISTINCT FROM` expression --- .../Query/ISqlExpressionFactory.cs | 8 ++ .../Query/QuerySqlGenerator.cs | 54 +++++++- .../Query/SqlExpressionFactory.cs | 20 +++ .../Query/SqlExpressionVisitor.cs | 8 ++ .../IsDistinctFromExpression.cs | 127 ++++++++++++++++++ .../Query/SqlNullabilityProcessor.cs | 36 +++-- 6 files changed, 242 insertions(+), 11 deletions(-) create mode 100644 src/EFCore.Relational/Query/SqlExpressions/IsDistinctFromExpression.cs diff --git a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs index 2712bec47ed..055cbfc4833 100644 --- a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs @@ -67,6 +67,14 @@ public interface ISqlExpressionFactory SqlExpression? existingExpression = null); // Comparison + /// + /// Creates a which represents an IS DISTINCT FROM expression. + /// + /// The left operand. + /// The right operand. + /// An expression representing a SQL IS DISTINCT FROM expression. + SqlExpression IsDistinctFrom(SqlExpression left, SqlExpression right); + /// /// Creates a which represents an equality comparison. /// diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs index 0c9f38b96a8..f932a86eb76 100644 --- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs +++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs @@ -825,6 +825,10 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio GenerateIn(inExpression, negated: true); break; + case IsDistinctFromExpression isDistinctFromExpression: + GenerateIsDistinctFrom(isDistinctFromExpression, negated: true); + break; + case ExistsExpression existsExpression: GenerateExists(existsExpression, negated: true); break; @@ -998,6 +1002,54 @@ protected virtual void GenerateIn(InExpression inExpression, bool negated) _relationalCommandBuilder.Append(")"); } + /// + /// Generates SQL for an IS DISTINCT FROM expression. + /// + /// The for which to generate SQL. + protected sealed override Expression VisitIsDistinctFrom(IsDistinctFromExpression isExpression) + { + GenerateIsDistinctFrom(isExpression, negated: false); + + return isExpression; + } + + /// + /// Generates SQL for an IS DISTINCT FROM expression. + /// + /// The for which to generate SQL. + /// Whether the given is negated. + protected virtual void GenerateIsDistinctFrom(IsDistinctFromExpression isDistinctFromExpression, bool negated) + { + var requiresBrackets = RequiresParentheses(isDistinctFromExpression, isDistinctFromExpression.Left); + if (requiresBrackets) + { + _relationalCommandBuilder.Append("("); + } + + Visit(isDistinctFromExpression.Left); + if (requiresBrackets) + { + _relationalCommandBuilder.Append(")"); + } + + _relationalCommandBuilder.Append(negated + ? " IS NOT DISTINCT FROM " + : " IS DISTINCT FROM " + ); + + requiresBrackets = RequiresParentheses(isDistinctFromExpression, isDistinctFromExpression.Right); + if (requiresBrackets) + { + _relationalCommandBuilder.Append("("); + } + + Visit(isDistinctFromExpression.Right); + if (requiresBrackets) + { + _relationalCommandBuilder.Append(")"); + } + } + /// /// Generates SQL for an AT TIME ZONE expression. /// @@ -1689,7 +1741,7 @@ protected virtual bool RequiresParentheses(SqlExpression outerExpression, SqlExp return true; } - case CollateExpression or LikeExpression or AtTimeZoneExpression or JsonScalarExpression: + case CollateExpression or LikeExpression or AtTimeZoneExpression or JsonScalarExpression or IsDistinctFromExpression: return !TryGetOperatorInfo(outerExpression, out outerPrecedence, out _) || !TryGetOperatorInfo(innerExpression, out innerPrecedence, out _) || outerPrecedence >= innerPrecedence; diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 064e97cbe74..9c22fa33cf4 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -52,6 +52,7 @@ public SqlExpressionFactory(SqlExpressionFactoryDependencies dependencies) ColumnExpression e => e.ApplyTypeMapping(typeMapping), DistinctExpression e => ApplyTypeMappingOnDistinct(e, typeMapping), InExpression e => ApplyTypeMappingOnIn(e), + IsDistinctFromExpression e => ApplyTypeMappingOnIsDistinctFrom(e), // We only do type inference for JSON scalar expression which represent a single array indexing operation; we can infer the // array's mapping from the element or vice versa, allowing e.g. parameter primitive collections to get inferred when an @@ -355,6 +356,21 @@ private InExpression ApplyTypeMappingOnIn(InExpression inExpression) : inExpression.ApplyTypeMapping(_boolTypeMapping); } + private IsDistinctFromExpression ApplyTypeMappingOnIsDistinctFrom(IsDistinctFromExpression isDistinctFromExpression) + { + var left = isDistinctFromExpression.Left; + var right = isDistinctFromExpression.Right; + var inferredTypeMapping = ExpressionExtensions.InferTypeMapping(left, right) + // We avoid object here since the result does not get typeMapping from outside. + ?? _typeMappingSource.FindMapping( + left.Type != typeof(object) ? left.Type : right.Type, + Dependencies.Model); + return new IsDistinctFromExpression( + ApplyTypeMapping(left, inferredTypeMapping), + ApplyTypeMapping(right, inferredTypeMapping), + _boolTypeMapping); + } + private SqlExpression ApplyTypeMappingOnJsonScalar( JsonScalarExpression jsonScalarExpression, RelationalTypeMapping? elementMapping) @@ -432,6 +448,10 @@ private SqlExpression ApplyTypeMappingOnJsonScalar( new SqlBinaryExpression(operatorType, left, right, returnType, null), typeMapping); } + /// + public virtual SqlExpression IsDistinctFrom(SqlExpression left, SqlExpression right) + => ApplyTypeMapping(new IsDistinctFromExpression(left, right, null), null); + /// public virtual SqlExpression Equal(SqlExpression left, SqlExpression right) => MakeBinary(ExpressionType.Equal, left, right, null)!; diff --git a/src/EFCore.Relational/Query/SqlExpressionVisitor.cs b/src/EFCore.Relational/Query/SqlExpressionVisitor.cs index bb4c44c9307..0186328554b 100644 --- a/src/EFCore.Relational/Query/SqlExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/SqlExpressionVisitor.cs @@ -34,6 +34,7 @@ ShapedQueryExpression shapedQueryExpression ExistsExpression existsExpression => VisitExists(existsExpression), FromSqlExpression fromSqlExpression => VisitFromSql(fromSqlExpression), InExpression inExpression => VisitIn(inExpression), + IsDistinctFromExpression isDistinctFromExpression => VisitIsDistinctFrom(isDistinctFromExpression), IntersectExpression intersectExpression => VisitIntersect(intersectExpression), InnerJoinExpression innerJoinExpression => VisitInnerJoin(innerJoinExpression), LeftJoinExpression leftJoinExpression => VisitLeftJoin(leftJoinExpression), @@ -144,6 +145,13 @@ ShapedQueryExpression shapedQueryExpression /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected abstract Expression VisitIn(InExpression inExpression); + /// + /// Visits the children of the IS DISTINCT FROM expression. + /// + /// The expression to visit. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. + protected abstract Expression VisitIsDistinctFrom(IsDistinctFromExpression isDistinctFromExpression); + /// /// Visits the children of the intersect expression. /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/IsDistinctFromExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/IsDistinctFromExpression.cs new file mode 100644 index 00000000000..468fe302203 --- /dev/null +++ b/src/EFCore.Relational/Query/SqlExpressions/IsDistinctFromExpression.cs @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; + +/// +/// +/// An expression that represents an IS DISTINCT FROM in a SQL tree. +/// +/// +/// This type is typically used by database providers (and other extensions). It is generally +/// not used in application code. +/// +/// +public class IsDistinctFromExpression : SqlExpression +{ + private static ConstructorInfo? _quotingConstructor; + + /// + /// Creates a new instance of the class. + /// + /// An expression which is left operand. + /// An expression which is right operand. + /// The associated with the expression. + public IsDistinctFromExpression( + SqlExpression left, + SqlExpression right, + RelationalTypeMapping? typeMapping) + : base(typeof(bool), typeMapping) + { + Left = left; + Right = right; + } + + /// + /// The left operand. + /// + public virtual SqlExpression Left { get; } + + /// + /// The right operand. + /// + public virtual SqlExpression Right { get; } + + /// + protected override Expression VisitChildren(ExpressionVisitor visitor) + { + var left = (SqlExpression)visitor.Visit(Left); + var right = (SqlExpression)visitor.Visit(Right); + + return Update(left, right); + } + + /// + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will + /// return this expression. + /// + /// The property of the result. + /// The property of the result. + /// This expression if no children changed, or an expression with the updated children. + public virtual IsDistinctFromExpression Update(SqlExpression left, SqlExpression right) + => left != Left || right != Right + ? new IsDistinctFromExpression(left, right, TypeMapping) + : this; + + /// + public override Expression Quote() + => New( + _quotingConstructor ??= typeof(IsDistinctFromExpression).GetConstructor( + [typeof(SqlExpression), typeof(SqlExpression), typeof(RelationalTypeMapping)])!, + Left.Quote(), + Right.Quote(), + RelationalExpressionQuotingUtilities.QuoteTypeMapping(TypeMapping)); + + /// + protected override void Print(ExpressionPrinter expressionPrinter) + { + var requiresBrackets = RequiresBrackets(Left); + + if (requiresBrackets) + { + expressionPrinter.Append("("); + } + + expressionPrinter.Visit(Left); + + if (requiresBrackets) + { + expressionPrinter.Append(")"); + } + + expressionPrinter.Append(" IS DISTINCT FROM "); + + requiresBrackets = RequiresBrackets(Right); + + if (requiresBrackets) + { + expressionPrinter.Append("("); + } + + expressionPrinter.Visit(Right); + + if (requiresBrackets) + { + expressionPrinter.Append(")"); + } + + static bool RequiresBrackets(SqlExpression expression) + => expression is SqlBinaryExpression or LikeExpression or InExpression; + } + + /// + public override bool Equals(object? obj) + => obj != null + && (ReferenceEquals(this, obj) + || obj is IsDistinctFromExpression isExpression + && Equals(isExpression)); + + private bool Equals(IsDistinctFromExpression isExpression) + => base.Equals(isExpression) + && Left.Equals(isExpression.Left) + && Right.Equals(isExpression.Right); + + /// + public override int GetHashCode() + => HashCode.Combine(base.GetHashCode(), Left, Right); +} diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 9a2513e4e6f..411c1d636e7 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -1126,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 @@ -1136,16 +1136,19 @@ protected virtual SqlExpression VisitSqlBinary( && (leftNullable || rightNullable) && !UseRelationalNulls) { - var rewriteNullSemanticsResult = RewriteNullSemantics( - updated, - updated.Left, - updated.Right, + // optimized expansion which doesn't distinguish between null and false + if (optimize && leftNullable != rightNullable && sqlBinaryExpression.OperatorType is ExpressionType.Equal) + { + nullable = true; + return OptimizeBooleanComparison(sqlBinaryExpression, left, right, optimize); + } + + return ApplyEqualityNullSemantics( + sqlBinaryExpression, leftNullable, rightNullable, optimize, out nullable); - - return rewriteNullSemanticsResult; } return optimized; @@ -1592,15 +1595,28 @@ private SqlExpression OptimizeBooleanComparison( : _sqlExpressionFactory.Equal(left, right); } - private SqlExpression RewriteNullSemantics( + /// + /// Transform an (in)equality expression into another expression that + /// takes null semantics into account, i.e. the resulting expression + /// returns true when comparing two `NULL`s and never returns `NULL` + /// except when `optimize` is true. + /// + /// The input (in)equality. + /// Whether the left sub-expression is nullable. + /// Whether the right sub-expression is nullable. + /// Whether a `NULL` is a valid alternative to `FALSE` in the result. + /// Whether the resulting expression is nullable. + /// An expression representing the given (in)equality. + protected virtual SqlExpression ApplyEqualityNullSemantics( SqlBinaryExpression sqlBinaryExpression, - SqlExpression left, - SqlExpression right, bool leftNullable, bool rightNullable, bool optimize, out bool nullable) { + var left = sqlBinaryExpression.Left; + var right = sqlBinaryExpression.Right; + var leftIsNull = ProcessNullNotNull(_sqlExpressionFactory.IsNull(left), leftNullable); var leftIsNotNull = _sqlExpressionFactory.Not(leftIsNull); From ab67714ad7f5a4373d698565c207c11df53a52fa Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sat, 13 Jul 2024 19:58:32 +0200 Subject: [PATCH 6/8] Use `IS` in Sqlite when appropriate --- .../Query/Internal/SqliteQuerySqlGenerator.cs | 31 +++++++++++++++++ .../Internal/SqliteSqlNullabilityProcessor.cs | 34 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs index ad1c62dc00e..c0dc5219dce 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs @@ -113,6 +113,36 @@ private void GenerateGlob(GlobExpression globExpression, bool negated = false) Visit(globExpression.Pattern); } + /// + protected override void GenerateIsDistinctFrom(IsDistinctFromExpression isExpression, bool negated) + { + var requiresBrackets = RequiresParentheses(isExpression, isExpression.Left); + if (requiresBrackets) + { + Sql.Append("("); + } + + Visit(isExpression.Left); + if (requiresBrackets) + { + Sql.Append(")"); + } + + Sql.Append(negated ? " IS " : " IS NOT "); + + requiresBrackets = RequiresParentheses(isExpression, isExpression.Right); + if (requiresBrackets) + { + Sql.Append("("); + } + + Visit(isExpression.Right); + if (requiresBrackets) + { + Sql.Append(")"); + } + } + private void GenerateRegexp(RegexpExpression regexpExpression, bool negated = false) { Visit(regexpExpression.Match); @@ -400,6 +430,7 @@ protected override bool TryGetOperatorInfo(SqlExpression expression, out int pre }, CollateExpression => (1100, false), + IsDistinctFromExpression => (500, false), LikeExpression => (500, false), JsonScalarExpression => (1000, true), diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs index 9a0cd639c3b..d6958a52f64 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal; @@ -14,6 +15,8 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal; /// public class SqliteSqlNullabilityProcessor : SqlNullabilityProcessor { + private static readonly bool _useIsDistinctFrom = new Version(new SqliteConnection().ServerVersion) >= new Version(3, 8, 11); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -108,6 +111,37 @@ protected override SqlExpression VisitSqlFunction( return result; } + /// + protected override SqlExpression ApplyEqualityNullSemantics( + SqlBinaryExpression sqlBinaryExpression, + bool leftNullable, + bool rightNullable, + bool optimize, + out bool nullable) + { + if (_useIsDistinctFrom) + { + var sqlExpressionFactory = Dependencies.SqlExpressionFactory; + + var body = sqlBinaryExpression is SqlBinaryExpression + { + Left: SqlUnaryExpression { OperatorType: ExpressionType.Not } left, + Right: SqlUnaryExpression { OperatorType: ExpressionType.Not } right + } + ? sqlExpressionFactory.IsDistinctFrom(left.Operand, right.Operand) + : sqlExpressionFactory.IsDistinctFrom(sqlBinaryExpression.Left, sqlBinaryExpression.Right); + + nullable = false; + return sqlBinaryExpression.OperatorType is ExpressionType.Equal + ? sqlExpressionFactory.Not(body) + : body; + } + else + { + return base.ApplyEqualityNullSemantics(sqlBinaryExpression, leftNullable, rightNullable, optimize, out nullable); + } + } + #pragma warning disable EF1001 /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to From be671f2702ee3747f3907a8c0e303b3ec681a386 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sat, 13 Jul 2024 19:58:32 +0200 Subject: [PATCH 7/8] Use `IS DISTINCT FROM` on modern SqlServer when appropriate --- .../Internal/SearchConditionConverter.cs | 5 +- .../SqlServerParameterBasedSqlProcessor.cs | 7 ++- ...ServerParameterBasedSqlProcessorFactory.cs | 9 +++- .../Internal/SqlServerQuerySqlGenerator.cs | 1 + .../SqlServerSqlNullabilityProcessor.cs | 51 +++++++++++++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/EFCore.SqlServer/Query/Internal/SearchConditionConverter.cs b/src/EFCore.SqlServer/Query/Internal/SearchConditionConverter.cs index 5a27b5e09a2..ca5eaa475be 100644 --- a/src/EFCore.SqlServer/Query/Internal/SearchConditionConverter.cs +++ b/src/EFCore.SqlServer/Query/Internal/SearchConditionConverter.cs @@ -53,7 +53,7 @@ public class SearchConditionConverter(ISqlExpressionFactory sqlExpressionFactory // The following are search condition expressions: they can appear directly in a WHERE, and cannot e.g. be projected out // directly SqlExpression e and - (ExistsExpression or InExpression or LikeExpression or SqlFunctionExpression { Name: "FREETEXT" or "CONTAINS" }) + (ExistsExpression or InExpression or IsDistinctFromExpression or LikeExpression or SqlFunctionExpression { Name: "FREETEXT" or "CONTAINS" }) => ApplyConversion((SqlExpression)base.VisitExtension(e), inSearchConditionContext, isExpressionSearchCondition: true), SqlExpression e => ApplyConversion( @@ -268,7 +268,8 @@ protected virtual Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression when (sqlUnaryExpression.TypeMapping?.Converter?.ProviderClrType ?? sqlUnaryExpression.Type) == typeof(bool): { // when possible, avoid converting to/from predicate form - if (!inSearchConditionContext && sqlUnaryExpression.Operand is not (ExistsExpression or InExpression or LikeExpression)) + if (!inSearchConditionContext && sqlUnaryExpression.Operand + is not (ExistsExpression or InExpression or IsDistinctFromExpression or LikeExpression)) { var negatedOperand = (SqlExpression)Visit(sqlUnaryExpression.Operand); diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs index f23d3c50e6d..9b08e5c12d2 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessor.cs @@ -1,6 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// @@ -11,6 +13,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// public class SqlServerParameterBasedSqlProcessor( RelationalParameterBasedSqlProcessorDependencies dependencies, + ISqlServerSingletonOptions sqlServerSingletonOptions, RelationalParameterBasedSqlProcessorParameters parameters) : RelationalParameterBasedSqlProcessor(dependencies, parameters) { @@ -44,7 +47,7 @@ protected override Expression ProcessSqlNullability( Check.NotNull(selectExpression, nameof(selectExpression)); Check.NotNull(parametersValues, nameof(parametersValues)); - return new SqlServerSqlNullabilityProcessor(Dependencies, Parameters).Process( + return new SqlServerSqlNullabilityProcessor(Dependencies, sqlServerSingletonOptions, Parameters).Process( selectExpression, parametersValues, out canCache); } } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs index 6cf2826794b..3319a024368 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// @@ -9,7 +11,10 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerParameterBasedSqlProcessorFactory(RelationalParameterBasedSqlProcessorDependencies dependencies) : IRelationalParameterBasedSqlProcessorFactory +public class SqlServerParameterBasedSqlProcessorFactory( + RelationalParameterBasedSqlProcessorDependencies dependencies, + ISqlServerSingletonOptions sqlServerSingletonOptions +) : IRelationalParameterBasedSqlProcessorFactory { /// /// Relational provider-specific dependencies for this service. @@ -23,5 +28,5 @@ public class SqlServerParameterBasedSqlProcessorFactory(RelationalParameterBased /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual RelationalParameterBasedSqlProcessor Create(RelationalParameterBasedSqlProcessorParameters parameters) - => new SqlServerParameterBasedSqlProcessor(Dependencies, parameters); + => new SqlServerParameterBasedSqlProcessor(Dependencies, sqlServerSingletonOptions, parameters); } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs index dfb054b097f..48002f57b99 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs @@ -700,6 +700,7 @@ protected override bool TryGetOperatorInfo(SqlExpression expression, out int pre CollateExpression => (900, false), LikeExpression => (350, false), + IsDistinctFromExpression => (500, false), AtTimeZoneExpression => (1200, false), // On SQL Server, JsonScalarExpression renders as a function (JSON_VALUE()), so there's never a need for parentheses. diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs index be0ac47926e..324d1aee600 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; +using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -14,9 +15,21 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// public class SqlServerSqlNullabilityProcessor( RelationalParameterBasedSqlProcessorDependencies dependencies, + ISqlServerSingletonOptions sqlServerSingletonOptions, RelationalParameterBasedSqlProcessorParameters parameters) : SqlNullabilityProcessor(dependencies, parameters) { + // CHECKME: + // https://learn.microsoft.com/en-us/sql/t-sql/queries/is-distinct-from-transact-sql + // only specifies the version for SQL Server 2022 (16.x) + private readonly bool _useIsDistinctFrom = sqlServerSingletonOptions.EngineType switch + { + SqlServerEngineType.SqlServer => sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160, + SqlServerEngineType.AzureSql => false, + SqlServerEngineType.AzureSynapse => false, + _ => false, + }; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -96,6 +109,44 @@ protected virtual SqlExpression VisitSqlServerAggregateFunction( : aggregateFunctionExpression; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected override SqlExpression ApplyEqualityNullSemantics( + SqlBinaryExpression sqlBinaryExpression, + bool leftNullable, + bool rightNullable, + bool optimize, + out bool nullable) + { + if (_useIsDistinctFrom + && IsSupportedSubExpression(sqlBinaryExpression.Left, leftNullable) + && IsSupportedSubExpression(sqlBinaryExpression.Right, rightNullable)) + { + var sqlExpressionFactory = Dependencies.SqlExpressionFactory; + var body = sqlExpressionFactory.IsDistinctFrom(sqlBinaryExpression.Left, sqlBinaryExpression.Right); + + nullable = false; + return sqlBinaryExpression.OperatorType is ExpressionType.Equal + ? sqlExpressionFactory.Not(body) + : body; + } + + return base.ApplyEqualityNullSemantics(sqlBinaryExpression, leftNullable, rightNullable, optimize, out nullable); + + // The provider for SqlServer is unable to translate `bool?` expressions + // when they are on Boolean values instead of `BIT`s. See #34001 + static bool IsSupportedSubExpression(SqlExpression sqlExpression, bool nullable) => + !nullable + || sqlExpression.Type != typeof(bool) + || sqlExpression is ColumnExpression or SqlConstantExpression or SqlParameterExpression + || sqlExpression is SqlUnaryExpression { OperatorType: ExpressionType.Not } unary + && IsSupportedSubExpression(unary.Operand, nullable); + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in From 18bdea8ad49852e849ba597920a5d81a6d2f1c9d Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Thu, 4 Jul 2024 16:03:18 +0200 Subject: [PATCH 8/8] Update baselines --- ...ComplexNavigationsQuerySqlServer160Test.cs | 110 +++----- ...igationsSharedTypeQuerySqlServer160Test.cs | 248 ++++++------------ ...imitiveCollectionsQuerySqlServer160Test.cs | 2 +- .../NorthwindBulkUpdatesSqliteTest.cs | 8 +- .../Query/ComplexTypeQuerySqliteTest.cs | 8 +- .../Query/GearsOfWarQuerySqliteTest.cs | 155 ++++++----- .../Query/NullSemanticsQuerySqliteTest.cs | 224 ++++++++-------- .../PrimitiveCollectionsQuerySqliteTest.cs | 2 +- 8 files changed, 310 insertions(+), 447 deletions(-) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs index 69f02149536..fb44ed75191 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs @@ -739,7 +739,7 @@ public override async Task Where_nav_prop_reference_optional2(bool async) SELECT [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -WHERE [l0].[Name] = N'L2 05' OR [l0].[Name] <> N'L2 42' OR [l0].[Name] IS NULL +WHERE [l0].[Name] = N'L2 05' OR [l0].[Name] IS DISTINCT FROM N'L2 42' """); } @@ -753,7 +753,7 @@ SELECT [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[Level1_Optional_Id] -WHERE [l0].[Name] = N'L2 05' OR [l1].[Name] <> N'L2 42' OR [l1].[Name] IS NULL +WHERE [l0].[Name] = N'L2 05' OR [l1].[Name] IS DISTINCT FROM N'L2 42' """); } @@ -780,7 +780,7 @@ public override async Task Where_multiple_nav_prop_reference_optional_member_com FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] -WHERE [l1].[Name] <> N'L3 05' OR [l1].[Name] IS NULL +WHERE [l1].[Name] IS DISTINCT FROM N'L3 05' """); } @@ -918,7 +918,7 @@ public override async Task Where_multiple_nav_prop_optional_required(bool async) FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] -WHERE [l1].[Name] <> N'L3 05' OR [l1].[Name] IS NULL +WHERE [l1].[Name] IS DISTINCT FROM N'L3 05' """); } @@ -974,7 +974,7 @@ FROM [LevelOne] AS [l] CROSS JOIN [LevelTwo] AS [l0] LEFT JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[Level1_Optional_Id] INNER JOIN [LevelOne] AS [l2] ON [l0].[Level1_Required_Id] = [l2].[Id] -WHERE [l1].[Name] = N'L2 01' OR [l2].[Name] <> N'Bar' OR [l2].[Name] IS NULL +WHERE [l1].[Name] = N'L2 01' OR [l2].[Name] IS DISTINCT FROM N'Bar' """); } @@ -988,7 +988,7 @@ SELECT [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] -WHERE [l1].[Name] = N'L3 05' OR [l0].[Name] <> N'L2 05' OR [l0].[Name] IS NULL +WHERE [l1].[Name] = N'L3 05' OR [l0].[Name] IS DISTINCT FROM N'L2 05' """); } @@ -1003,7 +1003,7 @@ FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id] LEFT JOIN [LevelThree] AS [l2] ON [l1].[Id] = [l2].[Level2_Optional_Id] -WHERE [l0].[Name] <> N'L2 05' OR [l0].[Name] IS NULL OR [l2].[Name] = N'L3 05' +WHERE [l0].[Name] IS DISTINCT FROM N'L2 05' OR [l2].[Name] = N'L3 05' """); } @@ -1018,7 +1018,7 @@ FROM [LevelThree] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Level2_Optional_Id] = [l0].[Id] INNER JOIN [LevelTwo] AS [l1] ON [l].[Level2_Required_Id] = [l1].[Id] LEFT JOIN [LevelOne] AS [l2] ON [l1].[Level1_Optional_Id] = [l2].[Id] -WHERE [l0].[Name] <> N'L2 05' OR [l0].[Name] IS NULL OR [l2].[Name] = N'L1 05' +WHERE [l0].[Name] IS DISTINCT FROM N'L2 05' OR [l2].[Name] = N'L1 05' """); } @@ -1033,7 +1033,7 @@ FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] LEFT JOIN [LevelThree] AS [l2] ON [l0].[Id] = [l2].[Level2_Optional_Id] -WHERE ([l1].[Id] = [l2].[Id] OR ([l1].[Id] IS NULL AND [l2].[Id] IS NULL)) AND ([l2].[Id] <> 7 OR [l2].[Id] IS NULL) +WHERE [l1].[Id] IS NOT DISTINCT FROM [l2].[Id] AND [l2].[Id] IS DISTINCT FROM 7 """); } @@ -1048,7 +1048,7 @@ FROM [LevelThree] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Level2_Required_Id] = [l0].[Id] INNER JOIN [LevelOne] AS [l1] ON [l0].[Level1_Required_Id] = [l1].[Id] LEFT JOIN [LevelOne] AS [l2] ON [l0].[Level1_Optional_Id] = [l2].[Id] -WHERE ([l1].[Id] <> [l2].[Id] OR [l2].[Id] IS NULL) AND ([l2].[Id] <> 7 OR [l2].[Id] IS NULL) +WHERE [l1].[Id] IS DISTINCT FROM [l2].[Id] AND [l2].[Id] IS DISTINCT FROM 7 """); } @@ -1189,7 +1189,7 @@ public override async Task Include_with_optional_navigation(bool async) SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -WHERE [l0].[Name] <> N'L2 05' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'L2 05' """); } @@ -2138,7 +2138,7 @@ SELECT [l1].[Name] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] LEFT JOIN [LevelOne] AS [l1] ON [l0].[Level1_Required_Id] = [l1].[Id] -WHERE [l1].[Name] <> N'L3 02' OR [l1].[Name] IS NULL +WHERE [l1].[Name] IS DISTINCT FROM N'L3 02' """); } @@ -2530,7 +2530,7 @@ public override async Task Optional_navigation_in_subquery_with_unrelated_projec SELECT TOP(@p) [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -WHERE [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'Foo' ORDER BY [l].[Id] """); } @@ -2546,7 +2546,7 @@ public override async Task Explicit_GroupJoin_in_subquery_with_unrelated_project SELECT TOP(@p) [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -WHERE [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'Foo' ORDER BY [l].[Id] """); } @@ -2562,7 +2562,7 @@ SELECT [s].[Id] SELECT DISTINCT [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_Optional_Id] - WHERE [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL + WHERE [l0].[Name] IS DISTINCT FROM N'Foo' ) AS [s] """); } @@ -2576,7 +2576,7 @@ public override async Task Explicit_GroupJoin_in_subquery_with_unrelated_project SELECT DISTINCT [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -WHERE [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'Foo' """); } @@ -2593,7 +2593,7 @@ SELECT TOP(@p) [s].[Id] SELECT DISTINCT [l].[Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] - WHERE [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL + WHERE [l0].[Name] IS DISTINCT FROM N'Foo' ) AS [s] ORDER BY [s].[Id] """); @@ -2660,7 +2660,7 @@ public override async Task Join_condition_optimizations_applied_correctly_when_a """ 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] -INNER JOIN [LevelTwo] AS [l0] ON [l].[OneToMany_Optional_Self_Inverse1Id] = [l0].[Level1_Optional_Id] OR ([l].[OneToMany_Optional_Self_Inverse1Id] IS NULL AND [l0].[Level1_Optional_Id] IS NULL) +INNER JOIN [LevelTwo] AS [l0] ON [l].[OneToMany_Optional_Self_Inverse1Id] IS NOT DISTINCT FROM [l0].[Level1_Optional_Id] """); } @@ -2672,7 +2672,7 @@ public override async Task Join_condition_optimizations_applied_correctly_when_a """ 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] -INNER JOIN [LevelTwo] AS [l0] ON ([l].[OneToMany_Optional_Self_Inverse1Id] = [l0].[Level1_Optional_Id] OR ([l].[OneToMany_Optional_Self_Inverse1Id] IS NULL AND [l0].[Level1_Optional_Id] IS NULL)) AND ([l].[OneToOne_Optional_Self1Id] = [l0].[OneToMany_Optional_Self_Inverse2Id] OR ([l].[OneToOne_Optional_Self1Id] IS NULL AND [l0].[OneToMany_Optional_Self_Inverse2Id] IS NULL)) +INNER JOIN [LevelTwo] AS [l0] ON [l].[OneToMany_Optional_Self_Inverse1Id] IS NOT DISTINCT FROM [l0].[Level1_Optional_Id] AND [l].[OneToOne_Optional_Self1Id] IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Self_Inverse2Id] """); } @@ -2705,7 +2705,7 @@ public override async Task Navigation_with_same_navigation_compared_to_null(bool SELECT [l].[Id] FROM [LevelTwo] AS [l] INNER JOIN [LevelOne] AS [l0] ON [l].[OneToMany_Required_Inverse2Id] = [l0].[Id] -WHERE [l0].[Name] <> N'L1 07' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'L1 07' """); } @@ -2733,7 +2733,7 @@ SELECT [l].[Id] FROM [LevelThree] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[OneToMany_Optional_Inverse3Id] = [l0].[Id] LEFT JOIN [LevelOne] AS [l1] ON [l0].[Level1_Required_Id] = [l1].[Id] -WHERE ([l1].[Name] <> N'L1 07' OR [l1].[Name] IS NULL) AND [l1].[Id] IS NOT NULL +WHERE [l1].[Name] IS DISTINCT FROM N'L1 07' AND [l1].[Id] IS NOT NULL """); } @@ -2857,11 +2857,7 @@ SELECT CASE SELECT TOP(1) [l1].[Name] FROM [LevelTwo] AS [l0] INNER JOIN [LevelOne] AS [l1] ON [l0].[Level1_Required_Id] = [l1].[Id] - ORDER BY [l0].[Id]) = N'L1 02' AND ( - SELECT TOP(1) [l1].[Name] - FROM [LevelTwo] AS [l0] - INNER JOIN [LevelOne] AS [l1] ON [l0].[Level1_Required_Id] = [l1].[Id] - ORDER BY [l0].[Id]) IS NOT NULL THEN CAST(1 AS bit) + ORDER BY [l0].[Id]) IS NOT DISTINCT FROM N'L1 02' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END FROM [LevelTwo] AS [l] @@ -3250,7 +3246,7 @@ public override async Task Include8(bool async) SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id], [l0].[Id], [l0].[Date], [l0].[Name], [l0].[OneToMany_Optional_Self_Inverse1Id], [l0].[OneToMany_Required_Self_Inverse1Id], [l0].[OneToOne_Optional_Self1Id] FROM [LevelTwo] AS [l] LEFT JOIN [LevelOne] AS [l0] ON [l].[Level1_Optional_Id] = [l0].[Id] -WHERE [l0].[Name] <> N'Fubar' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'Fubar' """); } @@ -3263,7 +3259,7 @@ public override async Task Include9(bool async) SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id], [l0].[Id], [l0].[Date], [l0].[Name], [l0].[OneToMany_Optional_Self_Inverse1Id], [l0].[OneToMany_Required_Self_Inverse1Id], [l0].[OneToOne_Optional_Self1Id] FROM [LevelTwo] AS [l] LEFT JOIN [LevelOne] AS [l0] ON [l].[Level1_Optional_Id] = [l0].[Id] -WHERE [l0].[Name] <> N'Fubar' OR [l0].[Name] IS NULL +WHERE [l0].[Name] IS DISTINCT FROM N'Fubar' """); } @@ -3394,7 +3390,7 @@ public override async Task Include18_2(bool async) SELECT DISTINCT [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 [l0].[Name] <> N'Foo' OR [l0].[Name] IS NULL + WHERE [l0].[Name] IS DISTINCT FROM N'Foo' ) AS [s] LEFT JOIN [LevelTwo] AS [l1] ON [s].[Id] = [l1].[Level1_Optional_Id] """); @@ -3595,19 +3591,7 @@ FROM [LevelThree] AS [l1] ORDER BY [l1].[Id]) FROM [LevelTwo] AS [l0] WHERE [l0].[Level1_Optional_Id] = [l].[Id] - ORDER BY [l0].[Id]) <> N'Foo' OR ( - SELECT TOP(1) ( - SELECT TOP(1) ( - SELECT TOP(1) [l2].[Name] - FROM [LevelFour] AS [l2] - WHERE [l2].[Level3_Required_Id] = [l1].[Id] - ORDER BY [l2].[Id]) - FROM [LevelThree] AS [l1] - WHERE [l1].[Level2_Required_Id] = [l0].[Id] - ORDER BY [l1].[Id]) - FROM [LevelTwo] AS [l0] - WHERE [l0].[Level1_Optional_Id] = [l].[Id] - ORDER BY [l0].[Id]) IS NULL + ORDER BY [l0].[Id]) IS DISTINCT FROM N'Foo' ORDER BY [l].[Id] """); } @@ -3684,15 +3668,11 @@ FROM [LevelThree] AS [l0] SELECT TOP(1) [l1].[Id] FROM [LevelTwo] AS [l1] WHERE [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] - ORDER BY [l1].[Id]) IS NOT NULL AND (( - SELECT TOP(1) [l2].[Id] - FROM [LevelTwo] AS [l2] - WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - ORDER BY [l2].[Id]) = [l0].[OneToMany_Optional_Inverse3Id] OR (( + ORDER BY [l1].[Id]) IS NOT NULL AND ( SELECT TOP(1) [l2].[Id] FROM [LevelTwo] AS [l2] WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - ORDER BY [l2].[Id]) IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] IS NULL)) + ORDER BY [l2].[Id]) IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ORDER BY [l0].[Id]) FROM [LevelOne] AS [l] """); @@ -3851,7 +3831,7 @@ FROM [LevelOne] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] INNER JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Required_Id] -LEFT JOIN [LevelOne] AS [l3] ON [l0].[Id] >= [l3].[Id] AND ([l2].[Name] = [l3].[Name] OR ([l2].[Name] IS NULL AND [l3].[Name] IS NULL)) +LEFT JOIN [LevelOne] AS [l3] ON [l0].[Id] >= [l3].[Id] AND [l2].[Name] IS NOT DISTINCT FROM [l3].[Name] """); } @@ -3925,7 +3905,7 @@ WHEN EXISTS ( SELECT 1 FROM [LevelOne] AS [l1] LEFT JOIN [LevelTwo] AS [l2] ON [l1].[Id] = [l2].[Level1_Optional_Id] - WHERE [l2].[Name] = [l0].[Name] OR ([l2].[Name] IS NULL AND [l0].[Name] IS NULL)) THEN CAST(1 AS bit) + WHERE [l2].[Name] IS NOT DISTINCT FROM [l0].[Name]) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [Contains] FROM [LevelOne] AS [l] @@ -3944,7 +3924,7 @@ WHEN EXISTS ( SELECT 1 FROM [LevelOne] AS [l2] LEFT JOIN [LevelTwo] AS [l3] ON [l2].[Id] = [l3].[Level1_Optional_Id] - WHERE [l3].[Id] = [l1].[Id] OR ([l3].[Id] IS NULL AND [l1].[Id] IS NULL)) THEN CAST(1 AS bit) + WHERE [l3].[Id] IS NOT DISTINCT FROM [l1].[Id]) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [Contains] FROM [LevelOne] AS [l] @@ -3970,7 +3950,7 @@ FROM [LevelOne] AS [l2] LEFT JOIN [LevelTwo] AS [l3] ON [l2].[Id] = [l3].[Id] LEFT JOIN [LevelThree] AS [l4] ON [l3].[Id] = [l4].[Id] LEFT JOIN [LevelTwo] AS [l5] ON [l2].[Id] = [l5].[Id] - WHERE [l1].[Name] = [l4].[Name] OR ([l1].[Name] IS NULL AND [l4].[Name] IS NULL)) > 0 + WHERE [l1].[Name] IS NOT DISTINCT FROM [l4].[Name]) > 0 """); } @@ -3999,7 +3979,7 @@ public override async Task GroupBy_aggregate_where_required_relationship(bool as FROM [LevelTwo] AS [l] INNER JOIN [LevelOne] AS [l0] ON [l].[OneToMany_Required_Inverse2Id] = [l0].[Id] GROUP BY [l0].[Id] -HAVING MAX([l].[Id]) <> 2 OR MAX([l].[Id]) IS NULL +HAVING MAX([l].[Id]) IS DISTINCT FROM 2 """); } @@ -4052,10 +4032,7 @@ FROM [LevelOne] AS [l] WHERE CASE WHEN [l0].[Id] IS NULL THEN NULL ELSE [l1].[Name] -END <> N'L' OR CASE - WHEN [l0].[Id] IS NULL THEN NULL - ELSE [l1].[Name] -END IS NULL +END IS DISTINCT FROM N'L' """); } @@ -4231,13 +4208,10 @@ FROM [LevelThree] AS [l0] WHERE ( SELECT TOP(1) [l1].[Id] FROM [LevelTwo] AS [l1] - WHERE [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] AND [l1].[Name] = N'L2 02') IS NOT NULL AND (( - SELECT TOP(1) [l2].[Id] - FROM [LevelTwo] AS [l2] - WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Name] = N'L2 02') = [l0].[OneToMany_Optional_Inverse3Id] OR (( + WHERE [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] AND [l1].[Name] = N'L2 02') IS NOT NULL AND ( SELECT TOP(1) [l2].[Id] FROM [LevelTwo] AS [l2] - WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Name] = N'L2 02') IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] IS NULL)) + WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Name] = N'L2 02') IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ORDER BY [l0].[Id]) AS [Pushdown] FROM [LevelOne] AS [l] WHERE [l].[Id] < 2 @@ -4454,7 +4428,7 @@ FROM [LevelOne] AS [l2] LEFT JOIN [LevelTwo] AS [l3] ON [l2].[Id] = [l3].[Id] LEFT JOIN [LevelThree] AS [l4] ON [l3].[Id] = [l4].[Id] LEFT JOIN [LevelTwo] AS [l5] ON [l2].[Id] = [l5].[Id] - WHERE [l1].[Name] = [l4].[Name] OR ([l1].[Name] IS NULL AND [l4].[Name] IS NULL)) > 0 + WHERE [l1].[Name] IS NOT DISTINCT FROM [l4].[Name]) > 0 """); } @@ -4801,15 +4775,11 @@ FROM [LevelThree] AS [l0] SELECT TOP(1) [l1].[Id] FROM [LevelTwo] AS [l1] WHERE [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] - ORDER BY [l1].[Id]) IS NOT NULL AND (( - SELECT TOP(1) [l2].[Id] - FROM [LevelTwo] AS [l2] - WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - ORDER BY [l2].[Id]) = [l0].[OneToMany_Optional_Inverse3Id] OR (( + ORDER BY [l1].[Id]) IS NOT NULL AND ( SELECT TOP(1) [l2].[Id] FROM [LevelTwo] AS [l2] WHERE [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - ORDER BY [l2].[Id]) IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] IS NULL)) + ORDER BY [l2].[Id]) IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ) AS [s] ORDER BY [l].[Id], [s].[Id0] """); @@ -4855,7 +4825,7 @@ public override async Task Multiple_select_many_in_projection(bool async) SELECT COUNT(*) FROM [LevelTwo] AS [l3] INNER JOIN [LevelThree] AS [l4] ON [l3].[Id] = [l4].[OneToMany_Optional_Inverse3Id] - WHERE [l].[Id] = [l3].[OneToMany_Optional_Inverse2Id] AND ([l4].[Name] <> N'' OR [l4].[Name] IS NULL)) + WHERE [l].[Id] = [l3].[OneToMany_Optional_Inverse2Id] AND [l4].[Name] IS DISTINCT FROM N'') FROM [LevelOne] AS [l] OUTER APPLY ( SELECT [s].[Id0] AS [Id], [l2].[Id] AS [RefId], [s].[Id] AS [Id0] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs index 075eaf6fffa..c3665da9b9b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs @@ -251,7 +251,7 @@ WHERE [l9].[OneToOne_Required_PK_Date] IS NOT NULL AND [l9].[Level1_Required_Id] ) AS [l10] ON [l4].[Id] = CASE WHEN [l10].[OneToOne_Required_PK_Date] IS NOT NULL AND [l10].[Level1_Required_Id] IS NOT NULL AND [l10].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l10].[Id] END - WHERE [l3].[Level3_Name] = [l7].[Level3_Name] OR ([l3].[Level3_Name] IS NULL AND [l7].[Level3_Name] IS NULL)) > 0 + WHERE [l3].[Level3_Name] IS NOT DISTINCT FROM [l7].[Level3_Name]) > 0 """); } @@ -357,7 +357,7 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_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 ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] - WHERE [s].[Level2_Name] <> N'Foo' OR [s].[Level2_Name] IS NULL + WHERE [s].[Level2_Name] IS DISTINCT FROM N'Foo' ) AS [s0] """); } @@ -428,10 +428,7 @@ WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] WHERE CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NULL OR [l1].[Level1_Required_Id] IS NULL OR [l1].[OneToMany_Required_Inverse2Id] IS NULL THEN NULL ELSE [l3].[Level3_Name] -END <> N'L' OR CASE - WHEN [l1].[OneToOne_Required_PK_Date] IS NULL OR [l1].[Level1_Required_Id] IS NULL OR [l1].[OneToMany_Required_Inverse2Id] IS NULL THEN NULL - ELSE [l3].[Level3_Name] -END IS NULL +END IS DISTINCT FROM N'L' """); } @@ -469,11 +466,9 @@ WHEN [l5].[Level2_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse3 END WHERE [l3].[Level3_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse4Id] IS NOT NULL AND CASE WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END IS NOT NULL AND (CASE - WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END = [l3].[OneToMany_Optional_Inverse4Id] OR (CASE + END IS NOT NULL AND CASE WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END IS NULL AND [l3].[OneToMany_Optional_Inverse4Id] IS NULL)) + END IS NOT DISTINCT FROM [l3].[OneToMany_Optional_Inverse4Id] ) AS [s] 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 AND [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] ) AS [s0] @@ -566,7 +561,7 @@ WHERE [l9].[OneToOne_Required_PK_Date] IS NOT NULL AND [l9].[Level1_Required_Id] ) AS [l10] ON [l4].[Id] = CASE WHEN [l10].[OneToOne_Required_PK_Date] IS NOT NULL AND [l10].[Level1_Required_Id] IS NOT NULL AND [l10].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l10].[Id] END - WHERE [l3].[Level3_Name] = [l7].[Level3_Name] OR ([l3].[Level3_Name] IS NULL AND [l7].[Level3_Name] IS NULL)) > 0 + WHERE [l3].[Level3_Name] IS NOT DISTINCT FROM [l7].[Level3_Name]) > 0 """); } @@ -901,7 +896,7 @@ WHERE [l6].[OneToOne_Required_PK_Date] IS NOT NULL AND [l6].[Level1_Required_Id] ) AS [l7] ON [s0].[Id] = CASE WHEN [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l7].[Id] END - WHERE [s].[Key] = [s0].[Key] OR ([s].[Key] IS NULL AND [s0].[Key] IS NULL)) AS [Sum] + WHERE [s].[Key] IS NOT DISTINCT FROM [s0].[Key]) AS [Sum] FROM ( SELECT 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] @@ -955,7 +950,7 @@ WHERE [l6].[OneToOne_Required_PK_Date] IS NOT NULL AND [l6].[Level1_Required_Id] ) AS [l7] ON [s0].[Id] = CASE WHEN [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l7].[Id] END - WHERE [s].[Key] = [s0].[Key] OR ([s].[Key] IS NULL AND [s0].[Key] IS NULL)) AS [Sum] + WHERE [s].[Key] IS NOT DISTINCT FROM [s0].[Key]) AS [Sum] FROM ( SELECT 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] @@ -995,13 +990,9 @@ WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] ) AS [l6] ON [l4].[Id] = [l6].[Level1_Optional_Id] WHERE CASE WHEN [l6].[OneToOne_Required_PK_Date] IS NOT NULL AND [l6].[Level1_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l6].[Id] - END = CASE - WHEN [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l3].[Id] - END OR (CASE - WHEN [l6].[OneToOne_Required_PK_Date] IS NOT NULL AND [l6].[Level1_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l6].[Id] - END IS NULL AND CASE + END IS NOT DISTINCT FROM CASE WHEN [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l3].[Id] - END IS NULL)) THEN CAST(1 AS bit) + END) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [Contains] FROM [Level1] AS [l] @@ -1045,7 +1036,7 @@ WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] ) AS [l8] ON [l3].[Id] = CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) AS [Max] + WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] IS NOT DISTINCT FROM [l6].[Id]) AS [Max] FROM [Level1] AS [l] LEFT JOIN ( SELECT [l0].[Id], [l0].[OneToOne_Required_PK_Date], [l0].[Level1_Required_Id], [l0].[OneToMany_Required_Inverse2Id] @@ -1077,7 +1068,7 @@ WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] ) AS [l8] ON [l3].[Id] = CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) < 2 OR ( + WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] IS NOT DISTINCT FROM [l6].[Id]) < 2 OR ( SELECT MAX(CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END) @@ -1097,7 +1088,7 @@ WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] ) AS [l8] ON [l3].[Id] = CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) > 2 + WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] IS NOT DISTINCT FROM [l6].[Id]) > 2 """); } @@ -1196,7 +1187,7 @@ WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] ) AS [l8] ON [l3].[Id] = CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) AS [Max] + WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] IS NOT DISTINCT FROM [l6].[Id]) AS [Max] FROM [Level1] AS [l] LEFT JOIN ( SELECT [l0].[Id], [l0].[OneToOne_Required_PK_Date], [l0].[Level1_Required_Id], [l0].[OneToMany_Required_Inverse2Id] @@ -1228,27 +1219,7 @@ WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] ) AS [l8] ON [l3].[Id] = CASE WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) <> 2 OR ( - SELECT MAX(CASE - WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] - END) - FROM [Level1] AS [l3] - LEFT JOIN ( - SELECT [l5].[Id], [l5].[OneToOne_Required_PK_Date], [l5].[Level1_Required_Id], [l5].[OneToMany_Required_Inverse2Id] - 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 - ) AS [l4] ON [l3].[Id] = CASE - WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] - END - LEFT JOIN [Level1] AS [l6] ON [l4].[OneToMany_Required_Inverse2Id] = [l6].[Id] - LEFT JOIN ( - SELECT [l7].[Id], [l7].[OneToOne_Required_PK_Date], [l7].[Level1_Required_Id], [l7].[OneToMany_Required_Inverse2Id] - FROM [Level1] AS [l7] - WHERE [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse2Id] IS NOT NULL - ) AS [l8] ON [l3].[Id] = CASE - WHEN [l8].[OneToOne_Required_PK_Date] IS NOT NULL AND [l8].[Level1_Required_Id] IS NOT NULL AND [l8].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l8].[Id] - END - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND ([l2].[Id] = [l6].[Id] OR ([l2].[Id] IS NULL AND [l6].[Id] IS NULL))) IS NULL + WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l2].[Id] IS NOT DISTINCT FROM [l6].[Id]) IS DISTINCT FROM 2 """); } @@ -1267,7 +1238,7 @@ LEFT JOIN ( FROM [Level1] AS [l3] WHERE [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL ) AS [l4] ON [l2].[Id] = [l4].[Level1_Optional_Id] - WHERE [l4].[Level2_Name] = [l1].[Level2_Name] OR ([l4].[Level2_Name] IS NULL AND [l1].[Level2_Name] IS NULL)) THEN CAST(1 AS bit) + WHERE [l4].[Level2_Name] IS NOT DISTINCT FROM [l1].[Level2_Name]) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [Contains] FROM [Level1] AS [l] @@ -1371,7 +1342,7 @@ WHEN [s0].[Level2_Required_Id] IS NOT NULL AND [s0].[OneToMany_Required_Inverse3 END = [s1].[Level3_Required_Id] LEFT JOIN [Level1] AS [l15] 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 >= [l15].[Id] AND ([s1].[Level4_Name] = [l15].[Name] OR ([s1].[Level4_Name] IS NULL AND [l15].[Name] IS NULL)) +END >= [l15].[Id] AND [s1].[Level4_Name] IS NOT DISTINCT FROM [l15].[Name] """); } @@ -1693,17 +1664,12 @@ SELECT TOP(1) 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 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 AND [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] AND [l1].[Level2_Name] = N'L2 02') IS NOT NULL 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 [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] AND [l1].[Level2_Name] = N'L2 02') IS NOT NULL AND ( SELECT TOP(1) 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 FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Level2_Name] = N'L2 02') = [l0].[OneToMany_Optional_Inverse3Id] OR (( - SELECT TOP(1) 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 - FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Level2_Name] = N'L2 02') IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] 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 [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] AND [l2].[Level2_Name] = N'L2 02') IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ORDER BY CASE WHEN [l0].[Level2_Required_Id] IS NOT NULL AND [l0].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l0].[Id] END) AS [Pushdown] @@ -2023,11 +1989,9 @@ WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3 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 + 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 IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL)) + END IS NOT DISTINCT FROM [l2].[OneToMany_Optional_Inverse3Id] ) AS [l3] ) """); @@ -2121,11 +2085,9 @@ SELECT CAST(LEN([l2].[Level3_Name]) AS int) 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 + 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 IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL)) + END IS NOT DISTINCT FROM [l2].[OneToMany_Optional_Inverse3Id] ) """); } @@ -2329,7 +2291,7 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] 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 [s] ON [l].[Id] = [s].[Level1_Optional_Id] LEFT JOIN [Level1] AS [l3] ON [s].[Level1_Required_Id] = [l3].[Id] -WHERE [l3].[Name] <> N'L3 02' OR [l3].[Name] IS NULL +WHERE [l3].[Name] IS DISTINCT FROM N'L3 02' """); } @@ -2758,7 +2720,7 @@ WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse ) AS [l3] ON 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 = [l3].[Level2_Required_Id] -WHERE [l3].[Level3_Name] <> N'L3 05' OR [l3].[Level3_Name] IS NULL +WHERE [l3].[Level3_Name] IS DISTINCT FROM N'L3 05' """); } @@ -3165,7 +3127,7 @@ FROM [Level1] AS [l3] WHERE [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL ) AS [l4] ON [l].[Id] = [l4].[Level1_Optional_Id] LEFT JOIN [Level1] AS [l5] ON [s].[Level1_Required_Id] = [l5].[Id] -WHERE [l4].[Level2_Name] = N'L2 01' OR [l5].[Name] <> N'Bar' OR [l5].[Name] IS NULL +WHERE [l4].[Level2_Name] = N'L2 01' OR [l5].[Name] IS DISTINCT FROM N'Bar' """); } @@ -3325,7 +3287,7 @@ WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] 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 LEFT JOIN [Level1] AS [l6] ON [l5].[Level1_Required_Id] = [l6].[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 [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l6].[Name] <> N'L1 07' OR [l6].[Name] IS NULL) AND [l6].[Id] 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 AND [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND [l6].[Name] IS DISTINCT FROM N'L1 07' AND [l6].[Id] IS NOT NULL """); } @@ -3416,7 +3378,7 @@ WHERE [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse ) AS [l5] ON CASE WHEN [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l3].[Id] END = [l5].[Level2_Optional_Id] -WHERE [l1].[Level2_Name] <> N'L2 05' OR [l1].[Level2_Name] IS NULL OR [l5].[Level3_Name] = N'L3 05' +WHERE [l1].[Level2_Name] IS DISTINCT FROM N'L2 05' OR [l5].[Level3_Name] = N'L3 05' """); } @@ -3515,13 +3477,9 @@ WHERE [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] ) AS [l4] ON [l].[Id] = [l4].[Level1_Optional_Id] WHERE CASE WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] -END = 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].[Id] -END OR (CASE - WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] -END IS NULL AND CASE +END IS NOT DISTINCT FROM 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].[Id] -END IS NULL) +END """); } @@ -3638,7 +3596,7 @@ WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse ) AS [l3] ON 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 = [l3].[Level2_Optional_Id] -WHERE [l3].[Level3_Name] <> N'L3 05' OR [l3].[Level3_Name] IS NULL +WHERE [l3].[Level3_Name] IS DISTINCT FROM N'L3 05' """); } @@ -3701,7 +3659,7 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_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 ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] - WHERE [s].[Level2_Name] <> N'Foo' OR [s].[Level2_Name] IS NULL + WHERE [s].[Level2_Name] IS DISTINCT FROM N'Foo' ) AS [s0] ORDER BY [s0].[Id] """); @@ -3832,7 +3790,7 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_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 ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] -WHERE [s].[Level2_Name] <> N'Foo' OR [s].[Level2_Name] IS NULL +WHERE [s].[Level2_Name] IS DISTINCT FROM N'Foo' """); } @@ -4131,7 +4089,7 @@ WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] END LEFT JOIN [Level1] AS [l2] ON [l1].[OneToMany_Required_Inverse2Id] = [l2].[Id] LEFT JOIN [Level1] AS [l3] ON [l1].[OneToOne_Optional_PK_Inverse2Id] = [l3].[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 ([l2].[Id] = [l3].[Id] OR ([l2].[Id] IS NULL AND [l3].[Id] IS 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 AND [l2].[Id] IS NOT DISTINCT FROM [l3].[Id] """); } @@ -4469,9 +4427,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] ) AS [l1] ON [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] WHERE 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 <> 6 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 +END IS DISTINCT FROM 6 """); } @@ -4560,7 +4516,7 @@ WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse ) AS [l3] ON 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 = [l3].[Level2_Required_Id] -WHERE [l3].[Level3_Name] = N'L3 05' OR [l1].[Level2_Name] <> N'L2 05' OR [l1].[Level2_Name] IS NULL +WHERE [l3].[Level3_Name] = N'L3 05' OR [l1].[Level2_Name] IS DISTINCT FROM N'L2 05' """); } @@ -4685,11 +4641,9 @@ SELECT 1 FROM [Level1] AS [l4] WHERE [l4].[Level3_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse4Id] IS NOT NULL AND CASE WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END IS NOT NULL AND (CASE - WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END = [l4].[OneToMany_Optional_Inverse4Id] OR (CASE + END IS NOT NULL AND CASE WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END IS NULL AND [l4].[OneToMany_Optional_Inverse4Id] IS NULL))) + END IS NOT DISTINCT FROM [l4].[OneToMany_Optional_Inverse4Id]) """); } @@ -4793,19 +4747,13 @@ WHERE [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse ) AS [l5] ON 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 = [l5].[Level2_Optional_Id] -WHERE (CASE - WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] -END = CASE - WHEN [l5].[Level2_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l5].[Id] -END OR (CASE +WHERE CASE WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] -END IS NULL AND CASE +END IS NOT DISTINCT FROM CASE WHEN [l5].[Level2_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l5].[Id] -END IS NULL)) AND (CASE +END AND CASE WHEN [l5].[Level2_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l5].[Id] -END <> 7 OR CASE - WHEN [l5].[Level2_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l5].[Id] -END IS NULL) +END IS DISTINCT FROM 7 """); } @@ -4889,11 +4837,9 @@ SELECT COUNT(*) 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 + 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 IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) AS [Count] + END IS NOT DISTINCT FROM [l2].[OneToMany_Optional_Inverse3Id]) AS [Count] FROM [Level1] AS [l] LEFT JOIN ( SELECT [l0].[Id], [l0].[OneToOne_Required_PK_Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[OneToMany_Required_Inverse2Id] @@ -4918,7 +4864,7 @@ 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 [l1].[Level2_Name] <> N'Foo' OR [l1].[Level2_Name] IS NULL + WHERE [l1].[Level2_Name] IS DISTINCT FROM N'Foo' ) AS [s] LEFT JOIN ( SELECT [l2].[Id], [l2].[OneToOne_Required_PK_Date], [l2].[Level1_Optional_Id], [l2].[Level1_Required_Id], [l2].[Level2_Name], [l2].[OneToMany_Optional_Inverse2Id], [l2].[OneToMany_Required_Inverse2Id], [l2].[OneToOne_Optional_PK_Inverse2Id] @@ -4957,7 +4903,7 @@ 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_Optional_Id] -WHERE [l1].[Level2_Name] <> N'L2 05' OR [l1].[Level2_Name] IS NULL +WHERE [l1].[Level2_Name] IS DISTINCT FROM N'L2 05' """); } @@ -5060,11 +5006,9 @@ SELECT COUNT(*) 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] - 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 + 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 IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0 + END IS NOT DISTINCT FROM [l6].[OneToMany_Optional_Inverse3Id]) > 0 """); } @@ -5779,7 +5723,7 @@ 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_Optional_Id] -WHERE [l1].[Level2_Name] = N'L2 05' OR [l1].[Level2_Name] <> N'L2 42' OR [l1].[Level2_Name] IS NULL +WHERE [l1].[Level2_Name] = N'L2 05' OR [l1].[Level2_Name] IS DISTINCT FROM N'L2 42' """); } @@ -5840,11 +5784,9 @@ SELECT 1 FROM [Level1] AS [l6] WHERE [l6].[Level3_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse4Id] IS NOT NULL AND CASE WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END IS NOT NULL AND (CASE - WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END = [l6].[OneToMany_Optional_Inverse4Id] OR (CASE + END IS NOT NULL AND CASE WHEN [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l3].[Id] - END IS NULL AND [l6].[OneToMany_Optional_Inverse4Id] IS NULL))) + END IS NOT DISTINCT FROM [l6].[OneToMany_Optional_Inverse4Id]) """); } @@ -6090,7 +6032,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_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 ) AS [s0] ON [l].[Id] = [s0].[Level1_Optional_Id] -WHERE [s].[Level2_Name] = N'L2 05' OR [s0].[Level2_Name] <> N'L2 42' OR [s0].[Level2_Name] IS NULL +WHERE [s].[Level2_Name] = N'L2 05' OR [s0].[Level2_Name] IS DISTINCT FROM N'L2 42' """); } @@ -6260,11 +6202,9 @@ SELECT COUNT(*) 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 + 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 IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0 + END IS NOT DISTINCT FROM [l2].[OneToMany_Optional_Inverse3Id]) > 0 """); } @@ -6508,7 +6448,7 @@ WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] END LEFT JOIN [Level1] AS [l6] ON [l5].[Level1_Required_Id] = [l6].[Id] LEFT JOIN [Level1] AS [l7] ON [l5].[Level1_Optional_Id] = [l7].[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 [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l6].[Id] <> [l7].[Id] OR [l6].[Id] IS NULL OR [l7].[Id] IS NULL) AND ([l6].[Id] IS NOT NULL OR [l7].[Id] IS NOT NULL) AND ([l7].[Id] <> 7 OR [l7].[Id] IS 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 AND [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND [l6].[Id] IS DISTINCT FROM [l7].[Id] AND [l7].[Id] IS DISTINCT FROM 7 """); } @@ -6755,7 +6695,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] 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 LEFT JOIN [Level1] AS [l2] ON [l1].[OneToMany_Required_Inverse2Id] = [l2].[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 ([l2].[Id] = [l2].[Id] OR [l2].[Id] IS 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 AND [l2].[Id] IS NOT DISTINCT FROM [l2].[Id] """); } @@ -6774,7 +6714,7 @@ 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_Optional_Id] -WHERE [l1].[Level2_Name] <> N'Foo' OR [l1].[Level2_Name] IS NULL +WHERE [l1].[Level2_Name] IS DISTINCT FROM N'Foo' ORDER BY [l].[Id] """); } @@ -6822,21 +6762,7 @@ WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL ORDER BY CASE WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] - END) = N'L1 02' AND ( - SELECT TOP(1) [l5].[Name] - FROM [Level1] AS [l2] - LEFT JOIN ( - SELECT [l3].[Id], [l3].[OneToOne_Required_PK_Date], [l3].[Level1_Required_Id], [l3].[OneToMany_Required_Inverse2Id] - FROM [Level1] AS [l3] - WHERE [l3].[OneToOne_Required_PK_Date] IS NOT NULL AND [l3].[Level1_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse2Id] IS NOT NULL - ) AS [l4] ON [l2].[Id] = CASE - WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] - END - LEFT JOIN [Level1] AS [l5] ON [l4].[Level1_Required_Id] = [l5].[Id] - WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL - ORDER BY CASE - WHEN [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l4].[Id] - END) IS NOT NULL THEN CAST(1 AS bit) + END) IS NOT DISTINCT FROM N'L1 02' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END FROM [Level1] AS [l] @@ -7161,7 +7087,7 @@ WHERE [l6].[OneToOne_Required_PK_Date] IS NOT NULL AND [l6].[Level1_Required_Id] WHEN [l7].[OneToOne_Required_PK_Date] IS NOT NULL AND [l7].[Level1_Required_Id] IS NOT NULL AND [l7].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l7].[Id] END LEFT JOIN [Level1] AS [l8] ON [l7].[Level1_Optional_Id] = [l8].[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 [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ([l5].[Level2_Name] <> N'L2 05' OR [l5].[Level2_Name] IS NULL OR [l8].[Name] = N'L1 05') +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 ([l5].[Level2_Name] IS DISTINCT FROM N'L2 05' OR [l8].[Name] = N'L1 05') """); } @@ -7339,7 +7265,7 @@ WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] 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 LEFT JOIN [Level1] AS [l2] ON [l1].[OneToMany_Required_Inverse2Id] = [l2].[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 ([l2].[Name] <> N'L1 07' OR [l2].[Name] IS NULL) AND [l2].[Id] 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 AND [l2].[Name] IS DISTINCT FROM N'L1 07' AND [l2].[Id] IS NOT NULL """); } @@ -7365,7 +7291,7 @@ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_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 ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] -WHERE [s].[Level2_Name] <> N'Foo' OR [s].[Level2_Name] IS NULL +WHERE [s].[Level2_Name] IS DISTINCT FROM N'Foo' ORDER BY [l].[Id] """); } @@ -7520,15 +7446,7 @@ 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 AND [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] ORDER BY 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 (( - SELECT TOP(1) 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 - FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - 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) = [l0].[OneToMany_Optional_Inverse3Id] OR (( + END) IS NOT NULL AND ( SELECT TOP(1) 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 @@ -7536,7 +7454,7 @@ FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] 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) IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] IS NULL)) + END) IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ORDER BY CASE WHEN [l0].[Level2_Required_Id] IS NOT NULL AND [l0].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l0].[Id] END) @@ -8044,7 +7962,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].[Id] <> @prm OR [l2].[Id] 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] IS DISTINCT FROM @prm ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] """); } @@ -8071,7 +7989,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].[Id] <> @prm OR [l2].[Id] 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] IS DISTINCT FROM @prm ) AS [s] ON [l].[Id] = [s].[Level1_Optional_Id] """); } @@ -8101,7 +8019,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].[Id] <> @prm1 OR [l2].[Id] 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] IS DISTINCT FROM @prm1 ) 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] @@ -8122,7 +8040,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 ([l7].[Id] <> @prm2 OR [l7].[Id] 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] IS DISTINCT FROM @prm2 ) 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] @@ -8154,7 +8072,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].[Id] <> @prm1 OR [l2].[Id] 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] IS DISTINCT FROM @prm1 ) 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] @@ -8175,7 +8093,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 ([l7].[Id] <> @prm2 OR [l7].[Id] 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] IS DISTINCT FROM @prm2 ) 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] @@ -8206,7 +8124,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].[Id] <> @prm OR [l2].[Id] 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] IS DISTINCT FROM @prm ) 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] @@ -8227,7 +8145,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 ([l7].[Id] <> @prm OR [l7].[Id] 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] IS DISTINCT FROM @prm ) 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] @@ -8258,7 +8176,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].[Id] <> @prm OR [l2].[Id] 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] IS DISTINCT FROM @prm ) 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] @@ -8279,7 +8197,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 ([l7].[Id] <> @prm OR [l7].[Id] 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] IS DISTINCT FROM @prm ) 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] @@ -8342,15 +8260,7 @@ 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 AND [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] ORDER BY 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 (( - SELECT TOP(1) 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 - FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] - 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) = [l0].[OneToMany_Optional_Inverse3Id] OR (( + END) IS NOT NULL AND ( SELECT TOP(1) 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 @@ -8358,7 +8268,7 @@ FROM [Level1] 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 AND [l].[Id] = [l2].[OneToMany_Optional_Inverse2Id] 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) IS NULL AND [l0].[OneToMany_Optional_Inverse3Id] IS NULL)) + END) IS NOT DISTINCT FROM [l0].[OneToMany_Optional_Inverse3Id] ) AS [s] ORDER BY [l].[Id], [s].[Id] """); @@ -8393,11 +8303,9 @@ WHEN [l5].[Level3_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse4 FROM [Level1] AS [l5] WHERE [l5].[Level3_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse4Id] IS NOT NULL AND CASE WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END IS NOT NULL AND (CASE - WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END = [l5].[OneToMany_Optional_Inverse4Id] OR (CASE + END IS NOT NULL AND CASE WHEN [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l2].[Id] - END IS NULL AND [l5].[OneToMany_Optional_Inverse4Id] IS NULL))), 0) > 1 THEN CAST(1 AS bit) + END IS NOT DISTINCT FROM [l5].[OneToMany_Optional_Inverse4Id]), 0) > 1 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [Result], [l0].[Id] AS [Id2], [l2].[Id] AS [Id3], [l4].[Id] AS [Id4], [l0].[OneToMany_Optional_Inverse2Id] FROM [Level1] AS [l0] @@ -8437,7 +8345,7 @@ WHERE [l6].[Level2_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse ) AS [l7] ON 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 = [l7].[OneToMany_Optional_Inverse3Id] - 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_Optional_Inverse2Id] AND ([l7].[Level3_Name] <> N'' OR [l7].[Level3_Name] 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 [l].[Id] = [l5].[OneToMany_Optional_Inverse2Id] AND [l7].[Level3_Name] IS DISTINCT FROM N'') FROM [Level1] AS [l] OUTER APPLY ( SELECT CASE diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index 1bc4bec3050..7b907496c41 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -1070,7 +1070,7 @@ public override async Task Nullable_reference_column_collection_index_equals_nul """ SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] FROM [PrimitiveCollectionsEntity] AS [p] -WHERE JSON_VALUE([p].[NullableStrings], '$[2]') = [p].[NullableString] OR (JSON_VALUE([p].[NullableStrings], '$[2]') IS NULL AND [p].[NullableString] IS NULL) +WHERE JSON_VALUE([p].[NullableStrings], '$[2]') IS NOT DISTINCT FROM [p].[NullableString] """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs index 25e9edd40c3..d3f4f70d8f1 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs @@ -212,7 +212,7 @@ DELETE FROM "Order Details" AS "o" SELECT ( SELECT "o1"."OrderID" FROM "Orders" AS "o1" - WHERE "o0"."CustomerID" = "o1"."CustomerID" OR ("o0"."CustomerID" IS NULL AND "o1"."CustomerID" IS NULL) + WHERE "o0"."CustomerID" IS "o1"."CustomerID" LIMIT 1) FROM "Orders" AS "o0" GROUP BY "o0"."CustomerID" @@ -236,7 +236,7 @@ SELECT 1 SELECT ( SELECT "o3"."OrderID" FROM "Orders" AS "o3" - WHERE "o2"."CustomerID" = "o3"."CustomerID" OR ("o2"."CustomerID" IS NULL AND "o3"."CustomerID" IS NULL) + WHERE "o2"."CustomerID" IS "o3"."CustomerID" LIMIT 1) FROM "Orders" AS "o2" GROUP BY "o2"."CustomerID" @@ -896,7 +896,7 @@ public override async Task Update_Where_GroupBy_First_set_constant(bool async) SELECT ( SELECT "o0"."CustomerID" FROM "Orders" AS "o0" - WHERE "o"."CustomerID" = "o0"."CustomerID" OR ("o"."CustomerID" IS NULL AND "o0"."CustomerID" IS NULL) + WHERE "o"."CustomerID" IS "o0"."CustomerID" LIMIT 1) FROM "Orders" AS "o" GROUP BY "o"."CustomerID" @@ -925,7 +925,7 @@ public override async Task Update_Where_GroupBy_First_set_constant_3(bool async) SELECT "c0"."CustomerID" FROM "Orders" AS "o0" LEFT JOIN "Customers" AS "c0" ON "o0"."CustomerID" = "c0"."CustomerID" - WHERE "o"."CustomerID" = "o0"."CustomerID" OR ("o"."CustomerID" IS NULL AND "o0"."CustomerID" IS NULL) + WHERE "o"."CustomerID" IS "o0"."CustomerID" LIMIT 1) FROM "Orders" AS "o" GROUP BY "o"."CustomerID" diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs index 7097461ff80..95277e206e4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs @@ -89,7 +89,7 @@ public override async Task Filter_on_required_property_inside_required_complex_t FROM "CustomerGroup" AS "c" LEFT JOIN "Customer" AS "c0" ON "c"."OptionalCustomerId" = "c0"."Id" INNER JOIN "Customer" AS "c1" ON "c"."RequiredCustomerId" = "c1"."Id" -WHERE "c0"."ShippingAddress_ZipCode" <> 7728 OR "c0"."ShippingAddress_ZipCode" IS NULL +WHERE "c0"."ShippingAddress_ZipCode" IS NOT 7728 """); } @@ -211,7 +211,7 @@ public override async Task Complex_type_equals_complex_type(bool async) """ SELECT "c"."Id", "c"."Name", "c"."BillingAddress_AddressLine1", "c"."BillingAddress_AddressLine2", "c"."BillingAddress_Tags", "c"."BillingAddress_ZipCode", "c"."BillingAddress_Country_Code", "c"."BillingAddress_Country_FullName", "c"."ShippingAddress_AddressLine1", "c"."ShippingAddress_AddressLine2", "c"."ShippingAddress_Tags", "c"."ShippingAddress_ZipCode", "c"."ShippingAddress_Country_Code", "c"."ShippingAddress_Country_FullName" FROM "Customer" AS "c" -WHERE "c"."ShippingAddress_AddressLine1" = "c"."BillingAddress_AddressLine1" AND ("c"."ShippingAddress_AddressLine2" = "c"."BillingAddress_AddressLine2" OR ("c"."ShippingAddress_AddressLine2" IS NULL AND "c"."BillingAddress_AddressLine2" IS NULL)) AND "c"."ShippingAddress_Tags" = "c"."BillingAddress_Tags" AND "c"."ShippingAddress_ZipCode" = "c"."BillingAddress_ZipCode" +WHERE "c"."ShippingAddress_AddressLine1" = "c"."BillingAddress_AddressLine1" AND "c"."ShippingAddress_AddressLine2" IS "c"."BillingAddress_AddressLine2" AND "c"."ShippingAddress_Tags" = "c"."BillingAddress_Tags" AND "c"."ShippingAddress_ZipCode" = "c"."BillingAddress_ZipCode" """); } @@ -458,7 +458,7 @@ public override async Task Filter_on_required_property_inside_required_struct_co FROM "ValuedCustomerGroup" AS "v" LEFT JOIN "ValuedCustomer" AS "v0" ON "v"."OptionalCustomerId" = "v0"."Id" INNER JOIN "ValuedCustomer" AS "v1" ON "v"."RequiredCustomerId" = "v1"."Id" -WHERE "v0"."ShippingAddress_ZipCode" <> 7728 OR "v0"."ShippingAddress_ZipCode" IS NULL +WHERE "v0"."ShippingAddress_ZipCode" IS NOT 7728 """); } @@ -581,7 +581,7 @@ public override async Task Struct_complex_type_equals_struct_complex_type(bool a """ SELECT "v"."Id", "v"."Name", "v"."BillingAddress_AddressLine1", "v"."BillingAddress_AddressLine2", "v"."BillingAddress_ZipCode", "v"."BillingAddress_Country_Code", "v"."BillingAddress_Country_FullName", "v"."ShippingAddress_AddressLine1", "v"."ShippingAddress_AddressLine2", "v"."ShippingAddress_ZipCode", "v"."ShippingAddress_Country_Code", "v"."ShippingAddress_Country_FullName" FROM "ValuedCustomer" AS "v" -WHERE "v"."ShippingAddress_AddressLine1" = "v"."BillingAddress_AddressLine1" AND ("v"."ShippingAddress_AddressLine2" = "v"."BillingAddress_AddressLine2" OR ("v"."ShippingAddress_AddressLine2" IS NULL AND "v"."BillingAddress_AddressLine2" IS NULL)) AND "v"."ShippingAddress_ZipCode" = "v"."BillingAddress_ZipCode" +WHERE "v"."ShippingAddress_AddressLine1" = "v"."BillingAddress_AddressLine1" AND "v"."ShippingAddress_AddressLine2" IS "v"."BillingAddress_AddressLine2" AND "v"."ShippingAddress_ZipCode" = "v"."BillingAddress_ZipCode" """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 3deb2933052..02179f5556a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -382,7 +382,7 @@ public override async Task Optional_navigation_type_compensation_works_with_DTOs SELECT "g"."SquadId" AS "Id" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' """); } @@ -538,7 +538,7 @@ public override async Task Correlated_collections_basic_projection_explicit_to_a LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -628,7 +628,7 @@ public override async Task Nullable_bool_comparison_is_translated_to_server(bool AssertSql( """ -SELECT "f"."Eradicated" = 1 AND "f"."Eradicated" IS NOT NULL AS "IsEradicated" +SELECT "f"."Eradicated" IS 1 AS "IsEradicated" FROM "Factions" AS "f" """); } @@ -703,7 +703,7 @@ public override async Task Correlated_collections_basic_projecting_constant_bool LEFT JOIN ( SELECT 1 AS "c", "w"."Id", "w"."OwnerFullName" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -961,7 +961,7 @@ public override async Task OfTypeNav3(bool async) LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" INNER JOIN "Weapons" AS "w" ON "g"."FullName" = "w"."OwnerFullName" LEFT JOIN "Tags" AS "t0" ON "g"."Nickname" = "t0"."GearNickName" AND "g"."SquadId" = "t0"."GearSquadId" -WHERE ("t"."Note" <> 'Foo' OR "t"."Note" IS NULL) AND "g"."Discriminator" = 'Officer' AND ("t0"."Note" <> 'Bar' OR "t0"."Note" IS NULL) +WHERE "t"."Note" IS NOT 'Foo' AND "g"."Discriminator" = 'Officer' AND "t0"."Note" IS NOT 'Bar' """); } @@ -987,7 +987,7 @@ SELECT NOT EXISTS ( SELECT 1 FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" - WHERE ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND NOT ("g"."HasSoulPatch")) + WHERE "t"."Note" IS NOT 'K.I.A.' AND NOT ("g"."HasSoulPatch")) """); } @@ -1142,7 +1142,7 @@ public override async Task Correlated_collections_basic_projection_ordered(bool LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId", "w0"."Name" DESC @@ -1236,7 +1236,7 @@ public override async Task Select_Singleton_Navigation_With_Member_Access(bool a SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "g"."Nickname" = 'Marcus' AND ("g"."CityOfBirthName" <> 'Ephyra' OR "g"."CityOfBirthName" IS NULL) +WHERE "g"."Nickname" = 'Marcus' AND "g"."CityOfBirthName" IS NOT 'Ephyra' """); } @@ -1249,7 +1249,7 @@ public override async Task String_compare_with_null_conditional_argument2(bool a SELECT "w0"."Id", "w0"."AmmunitionType", "w0"."IsAutomatic", "w0"."Name", "w0"."OwnerFullName", "w0"."SynergyWithId" FROM "Weapons" AS "w" LEFT JOIN "Weapons" AS "w0" ON "w"."SynergyWithId" = "w0"."Id" -ORDER BY 'Marcus'' Lancer' = "w0"."Name" AND "w0"."Name" IS NOT NULL +ORDER BY 'Marcus'' Lancer' IS "w0"."Name" """); } @@ -1439,7 +1439,7 @@ public override async Task OfTypeNav1(bool async) FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" LEFT JOIN "Tags" AS "t0" ON "g"."Nickname" = "t0"."GearNickName" AND "g"."SquadId" = "t0"."GearSquadId" -WHERE ("t"."Note" <> 'Foo' OR "t"."Note" IS NULL) AND "g"."Discriminator" = 'Officer' AND ("t0"."Note" <> 'Bar' OR "t0"."Note" IS NULL) +WHERE "t"."Note" IS NOT 'Foo' AND "g"."Discriminator" = 'Officer' AND "t0"."Note" IS NOT 'Bar' """); } @@ -1512,7 +1512,7 @@ public override async Task Correlated_collections_basic_projecting_single_proper LEFT JOIN ( SELECT "w"."Name", "w"."Id", "w"."OwnerFullName" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -1626,7 +1626,7 @@ public override async Task Select_multiple_conditions(bool async) AssertSql( """ -SELECT "w"."Id", NOT ("w"."IsAutomatic") AND "w"."SynergyWithId" = 1 AND "w"."SynergyWithId" IS NOT NULL AS "IsCartridge" +SELECT "w"."Id", NOT ("w"."IsAutomatic") AND "w"."SynergyWithId" IS 1 AS "IsCartridge" FROM "Weapons" AS "w" """); } @@ -1688,7 +1688,7 @@ public override async Task SelectMany_predicate_with_non_equality_comparison_Def """ SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Gears" AS "g" -LEFT JOIN "Weapons" AS "w" ON "g"."FullName" <> "w"."OwnerFullName" OR "w"."OwnerFullName" IS NULL +LEFT JOIN "Weapons" AS "w" ON "g"."FullName" IS NOT "w"."OwnerFullName" ORDER BY "g"."Nickname", "w"."Id" """); } @@ -1924,7 +1924,7 @@ public override async Task Optional_navigation_type_compensation_works_with_cont SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND "g"."SquadId" IN ( +WHERE "t"."Note" IS NOT 'K.I.A.' AND "g"."SquadId" IN ( SELECT "g0"."SquadId" FROM "Gears" AS "g0" ) @@ -1975,7 +1975,7 @@ CROSS JOIN "Squads" AS "s" LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" LEFT JOIN ( SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank" @@ -2167,7 +2167,7 @@ public override async Task Subquery_containing_join_gets_lifted_clashing_names(b FROM "Gears" AS "g" INNER JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" INNER JOIN "Tags" AS "t0" ON "g"."Nickname" = "t0"."GearNickName" -WHERE "t"."GearNickName" <> 'Cole Train' OR "t"."GearNickName" IS NULL +WHERE "t"."GearNickName" IS NOT 'Cole Train' ORDER BY "g"."Nickname", "t0"."Id" """); } @@ -2314,9 +2314,7 @@ SELECT CASE INNER JOIN "Factions" AS "f" ON "l"."Name" = "f"."CommanderName" WHERE CASE WHEN "f"."Name" = 'Locust' THEN 1 -END = 0 OR CASE - WHEN "f"."Name" = 'Locust' THEN 1 -END IS NULL +END IS NOT 1 """); } @@ -2462,7 +2460,7 @@ LEFT JOIN ( FROM "LocustLeaders" AS "l" WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" -WHERE "c"."Name" <> 'Foo' OR "c"."Name" IS NULL +WHERE "c"."Name" IS NOT 'Foo' """); } @@ -2475,7 +2473,7 @@ public override async Task Optional_navigation_type_compensation_works_with_orde SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' ORDER BY "g"."SquadId" """); } @@ -2568,7 +2566,7 @@ public override async Task Sum_with_optional_navigation_is_translated_to_sql(boo SELECT COALESCE(SUM("g"."SquadId"), 0) FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" -WHERE "t"."Note" <> 'Foo' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'Foo' """); } @@ -2623,7 +2621,7 @@ SELECT CASE END FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -LEFT JOIN "Tags" AS "t0" ON ("g"."Nickname" = "t0"."GearNickName" OR ("g"."Nickname" IS NULL AND "t0"."GearNickName" IS NULL)) AND ("g"."SquadId" = "t0"."GearSquadId" OR ("g"."SquadId" IS NULL AND "t0"."GearSquadId" IS NULL)) +LEFT JOIN "Tags" AS "t0" ON "g"."Nickname" IS "t0"."GearNickName" AND "g"."SquadId" IS "t0"."GearSquadId" LEFT JOIN "Gears" AS "g0" ON "t0"."GearNickName" = "g0"."Nickname" AND "t0"."GearSquadId" = "g0"."SquadId" LEFT JOIN "Cities" AS "c" ON "g0"."AssignedCityName" = "c"."Name" """); @@ -2670,7 +2668,7 @@ public override async Task Optional_navigation_type_compensation_works_with_nega SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND NOT ("g"."HasSoulPatch") +WHERE "t"."Note" IS NOT 'K.I.A.' AND NOT ("g"."HasSoulPatch") """); } @@ -2804,7 +2802,7 @@ LEFT JOIN ( FROM "Gears" AS "g0" ) AS "g1" WHERE "g1"."row" <= 50 -) AS "g2" ON ("g"."Nickname" = "g2"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g2"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g2"."LeaderSquadId" +) AS "g2" ON "g"."Nickname" IS "g2"."LeaderNickname" AND "g"."SquadId" = "g2"."LeaderSquadId" WHERE "g"."Discriminator" = 'Officer' ORDER BY "t"."Id", "g"."Nickname", "g"."SquadId", "g2"."Nickname" """); @@ -2938,7 +2936,7 @@ public override async Task FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" LEFT JOIN "Squads" AS "s" ON "g"."SquadId" = "s"."Id" -WHERE substr("t"."Note", 0 + 1, length("s"."Name")) = "t"."GearNickName" OR (("t"."Note" IS NULL OR "s"."Name" IS NULL) AND "t"."GearNickName" IS NULL) +WHERE substr("t"."Note", 0 + 1, length("s"."Name")) IS "t"."GearNickName" """); } @@ -3228,7 +3226,7 @@ public override async Task Coalesce_operator_in_projection_with_other_conditions AssertSql( """ -SELECT ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND COALESCE("g"."HasSoulPatch", 0) +SELECT "t"."Note" IS NOT 'K.I.A.' AND COALESCE("g"."HasSoulPatch", 0) FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" """); @@ -3326,7 +3324,7 @@ public override async Task SelectMany_without_result_selector_and_non_equality_c """ SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Gears" AS "g" -LEFT JOIN "Weapons" AS "w" ON "g"."FullName" <> "w"."OwnerFullName" OR "w"."OwnerFullName" IS NULL +LEFT JOIN "Weapons" AS "w" ON "g"."FullName" IS NOT "w"."OwnerFullName" """); } @@ -3465,7 +3463,7 @@ LEFT JOIN ( FROM "LocustLeaders" AS "l" WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" -WHERE ("c"."Name" <> 'Foo' OR "c"."Name" IS NULL) AND ("l0"."Name" <> 'Bar' OR "l0"."Name" IS NULL) +WHERE "c"."Name" IS NOT 'Foo' AND "l0"."Name" IS NOT 'Bar' """); } @@ -3532,7 +3530,7 @@ public override async Task Optional_navigation_type_compensation_works_with_arra SELECT "g"."SquadId" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' """); } @@ -3642,17 +3640,12 @@ public override async Task FirstOrDefault_navigation_access_entity_equality_in_w 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" LEFT JOIN "Cities" AS "c" ON "g"."AssignedCityName" = "c"."Name" -WHERE "c"."Name" = ( - SELECT "c0"."Name" - FROM "Gears" AS "g0" - INNER JOIN "Cities" AS "c0" ON "g0"."CityOfBirthName" = "c0"."Name" - ORDER BY "g0"."Nickname" - LIMIT 1) OR ("c"."Name" IS NULL AND ( +WHERE "c"."Name" IS ( SELECT "c0"."Name" FROM "Gears" AS "g0" INNER JOIN "Cities" AS "c0" ON "g0"."CityOfBirthName" = "c0"."Name" ORDER BY "g0"."Nickname" - LIMIT 1) IS NULL) + LIMIT 1) """); } @@ -3670,7 +3663,7 @@ LEFT JOIN ( FROM "LocustLeaders" AS "l" WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" -WHERE ("c"."Name" <> 'Foo' OR "c"."Name" IS NULL) AND ("l0"."Name" <> 'Bar' OR "l0"."Name" IS NULL) +WHERE "c"."Name" IS NOT 'Foo' AND "l0"."Name" IS NOT 'Bar' """); } @@ -3739,7 +3732,7 @@ LEFT JOIN ( SELECT "w0"."Id", "w0"."AmmunitionType", "w0"."IsAutomatic", "w0"."Name", "w0"."OwnerFullName", "w0"."SynergyWithId" FROM "Weapons" AS "w" LEFT JOIN "Weapons" AS "w0" ON "w"."SynergyWithId" = "w0"."Id" -) AS "s" ON "g"."FullName" <> "s"."OwnerFullName" OR "s"."OwnerFullName" IS NULL +) AS "s" ON "g"."FullName" IS NOT "s"."OwnerFullName" ORDER BY "g"."Nickname", "s"."Id" """); } @@ -4001,7 +3994,7 @@ public override async Task Coalesce_operator_in_predicate_with_other_conditions( SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND COALESCE("g"."HasSoulPatch", 0) +WHERE "t"."Note" IS NOT 'K.I.A.' AND COALESCE("g"."HasSoulPatch", 0) """); } @@ -4018,7 +4011,7 @@ LEFT JOIN ( SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "c"."Name", "c"."Location", "c"."Nation" FROM "Gears" AS "g0" INNER JOIN "Cities" AS "c" ON "g0"."CityOfBirthName" = "c"."Name" -) AS "s" ON ("g"."Nickname" = "s"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "s"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "s"."LeaderSquadId" +) AS "s" ON "g"."Nickname" IS "s"."LeaderNickname" AND "g"."SquadId" = "s"."LeaderSquadId" ORDER BY "l"."Name", "g"."Nickname", "g"."SquadId", "s"."Nickname", "s"."SquadId" """); } @@ -4245,7 +4238,7 @@ public override async Task Singleton_Navigation_With_Member_Access(bool async) SELECT "g"."CityOfBirthName" AS "B" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "g"."Nickname" = 'Marcus' AND ("g"."CityOfBirthName" <> 'Ephyra' OR "g"."CityOfBirthName" IS NULL) +WHERE "g"."Nickname" = 'Marcus' AND "g"."CityOfBirthName" IS NOT 'Ephyra' """); } @@ -4339,7 +4332,7 @@ public override async Task Double_order_by_on_string_compare(bool async) """ SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" -ORDER BY "w"."Name" = 'Marcus'' Lancer' AND "w"."Name" IS NOT NULL, "w"."Id" +ORDER BY "w"."Name" IS 'Marcus'' Lancer', "w"."Id" """); } @@ -4438,7 +4431,7 @@ public override async Task Optional_navigation_type_compensation_works_with_proj SELECT "g"."SquadId" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' """); } @@ -4486,7 +4479,7 @@ public override async Task Null_semantics_is_correctly_applied_for_function_comp SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE substr("t"."Note", 0 + 1, "g"."SquadId") = "t"."GearNickName" OR (("t"."Note" IS NULL OR "g"."SquadId" IS NULL) AND "t"."GearNickName" IS NULL) +WHERE substr("t"."Note", 0 + 1, "g"."SquadId") IS "t"."GearNickName" """); } @@ -4608,7 +4601,7 @@ public override async Task SelectMany_predicate_with_non_equality_comparison_con """ SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Gears" AS "g" -INNER JOIN "Weapons" AS "w" ON "g"."FullName" <> "w"."OwnerFullName" OR "w"."OwnerFullName" IS NULL +INNER JOIN "Weapons" AS "w" ON "g"."FullName" IS NOT "w"."OwnerFullName" ORDER BY "g"."Nickname", "w"."Id" """); } @@ -4636,7 +4629,7 @@ public override async Task Optional_navigation_type_compensation_works_with_pred SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE ("t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL) AND "g"."HasSoulPatch" +WHERE "t"."Note" IS NOT 'K.I.A.' AND "g"."HasSoulPatch" """); } @@ -4692,7 +4685,7 @@ LEFT JOIN ( FROM "Factions" AS "f" WHERE "f"."Name" = 'Swarm' ) AS "f0" ON "l"."Name" = "f0"."CommanderName" -WHERE "f0"."Eradicated" = 0 OR "f0"."Eradicated" IS NULL +WHERE "f0"."Eradicated" IS NOT 1 """); } @@ -4729,7 +4722,7 @@ public override async Task Include_with_nested_navigation_in_order_by(bool async FROM "Weapons" AS "w" LEFT JOIN "Gears" AS "g" ON "w"."OwnerFullName" = "g"."FullName" LEFT JOIN "Cities" AS "c" ON "g"."CityOfBirthName" = "c"."Name" -WHERE "g"."Nickname" <> 'Paduk' OR "g"."Nickname" IS NULL +WHERE "g"."Nickname" IS NOT 'Paduk' ORDER BY "c"."Name", "w"."Id" """); } @@ -4760,7 +4753,7 @@ INNER JOIN ( FROM "Factions" AS "f" WHERE "f"."Name" = 'Swarm' ) AS "f0" ON "l"."Name" = "f0"."CommanderName" -WHERE "f0"."Eradicated" = 0 OR "f0"."Eradicated" IS NULL +WHERE "f0"."Eradicated" IS NOT 1 """); } @@ -4866,7 +4859,7 @@ public override async Task String_compare_with_null_conditional_argument(bool as SELECT "w0"."Id", "w0"."AmmunitionType", "w0"."IsAutomatic", "w0"."Name", "w0"."OwnerFullName", "w0"."SynergyWithId" FROM "Weapons" AS "w" LEFT JOIN "Weapons" AS "w0" ON "w"."SynergyWithId" = "w0"."Id" -ORDER BY "w0"."Name" = 'Marcus'' Lancer' AND "w0"."Name" IS NOT NULL +ORDER BY "w0"."Name" IS 'Marcus'' Lancer' """); } @@ -4913,7 +4906,7 @@ public override async Task Project_collection_navigation_nested_composite_key(bo SELECT "t"."Id", "g"."Nickname", "g"."SquadId", "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -LEFT JOIN "Gears" AS "g0" ON ("g"."Nickname" = "g0"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g0"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g0"."LeaderSquadId" +LEFT JOIN "Gears" AS "g0" ON "g"."Nickname" IS "g0"."LeaderNickname" AND "g"."SquadId" = "g0"."LeaderSquadId" WHERE "g"."Discriminator" = 'Officer' ORDER BY "t"."Id", "g"."Nickname", "g"."SquadId", "g0"."Nickname" """); @@ -4989,7 +4982,7 @@ public override async Task Distinct_with_optional_navigation_is_translated_to_sq SELECT DISTINCT "g"."HasSoulPatch" FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" -WHERE "t"."Note" <> 'Foo' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'Foo' """); } @@ -5119,13 +5112,13 @@ public override async Task Accessing_derived_property_using_hard_and_soft_cast(b """ SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId" FROM "LocustLeaders" AS "l" -WHERE "l"."Discriminator" = 'LocustCommander' AND ("l"."HighCommandId" <> 0 OR "l"."HighCommandId" IS NULL) +WHERE "l"."Discriminator" = 'LocustCommander' AND "l"."HighCommandId" IS NOT 0 """, // """ SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId" FROM "LocustLeaders" AS "l" -WHERE "l"."Discriminator" = 'LocustCommander' AND ("l"."HighCommandId" <> 0 OR "l"."HighCommandId" IS NULL) +WHERE "l"."Discriminator" = 'LocustCommander' AND "l"."HighCommandId" IS NOT 0 """); } @@ -5657,7 +5650,7 @@ public override async Task Correlated_collections_basic_projection_explicit_to_l LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -5915,7 +5908,7 @@ public override async Task Select_correlated_filtered_collection(bool async) LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."Name" <> 'Lancer' OR "w"."Name" IS NULL + WHERE "w"."Name" IS NOT 'Lancer' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "c"."Name" IN ('Ephyra', 'Hanover') ORDER BY "g"."Nickname", "g"."SquadId", "c"."Name" @@ -6066,7 +6059,7 @@ LEFT JOIN ( WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" LEFT JOIN "Gears" AS "g" ON "l0"."DefeatedByNickname" = "g"."Nickname" AND "l0"."DefeatedBySquadId" = "g"."SquadId" -LEFT JOIN "Gears" AS "g0" ON ("g"."Nickname" = "g0"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g0"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g0"."LeaderSquadId" +LEFT JOIN "Gears" AS "g0" ON "g"."Nickname" IS "g0"."LeaderNickname" AND "g"."SquadId" = "g0"."LeaderSquadId" ORDER BY "f"."Id", "l0"."Name", "g"."Nickname", "g"."SquadId", "g0"."Nickname" """); } @@ -6082,7 +6075,7 @@ public override async Task Select_Where_Navigation_Scalar_Equals_Navigation_Scal CROSS JOIN "Tags" AS "t0" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" LEFT JOIN "Gears" AS "g0" ON "t0"."GearNickName" = "g0"."Nickname" AND "t0"."GearSquadId" = "g0"."SquadId" -WHERE "g"."Nickname" = "g0"."Nickname" OR ("g"."Nickname" IS NULL AND "g0"."Nickname" IS NULL) +WHERE "g"."Nickname" IS "g0"."Nickname" """); } @@ -6140,7 +6133,7 @@ LEFT JOIN ( LEFT JOIN "Squads" AS "s" ON "g3"."SquadId" = "s"."Id" LEFT JOIN "Weapons" AS "w0" ON "g3"."FullName" = "w0"."OwnerFullName" LEFT JOIN "Gears" AS "g4" ON "s"."Id" = "g4"."SquadId" - WHERE "w"."Name" <> 'Bar' OR "w"."Name" IS NULL + WHERE "w"."Name" IS NOT 'Bar' ) AS "s0" ON "g2"."FullName" = "s0"."OwnerFullName" WHERE "g2"."FullName" <> 'Foo' ) AS "s1" ON "g"."Nickname" = "s1"."LeaderNickname" AND "g"."SquadId" = "s1"."LeaderSquadId" @@ -6190,7 +6183,7 @@ public override async Task Bitwise_operation_with_null_arguments(bool async) SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" -WHERE "w"."AmmunitionType" & @prm <> 0 OR "w"."AmmunitionType" IS NULL +WHERE "w"."AmmunitionType" & @prm IS NOT 0 """, // """ @@ -6256,7 +6249,7 @@ public override async Task Include_on_derived_type_with_order_by_and_paging(bool SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId", "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator" AS "Discriminator0", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "t"."Id", "t"."Note" FROM "LocustLeaders" AS "l" LEFT JOIN "Gears" AS "g" ON "l"."DefeatedByNickname" = "g"."Nickname" AND "l"."DefeatedBySquadId" = "g"."SquadId" - LEFT JOIN "Tags" AS "t" ON ("g"."Nickname" = "t"."GearNickName" OR ("g"."Nickname" IS NULL AND "t"."GearNickName" IS NULL)) AND ("g"."SquadId" = "t"."GearSquadId" OR ("g"."SquadId" IS NULL AND "t"."GearSquadId" IS NULL)) + LEFT JOIN "Tags" AS "t" ON "g"."Nickname" IS "t"."GearNickName" AND "g"."SquadId" IS "t"."GearSquadId" ORDER BY "t"."Note" LIMIT @p ) AS "s" @@ -6473,7 +6466,7 @@ LEFT JOIN ( FROM "Gears" AS "g" WHERE "g"."Discriminator" = 'Officer' ) AS "g0" ON "t"."GearNickName" = "g0"."Nickname" -LEFT JOIN "Gears" AS "g1" ON ("g0"."Nickname" = "g1"."LeaderNickname" OR ("g0"."Nickname" IS NULL AND "g1"."LeaderNickname" IS NULL)) AND "g0"."SquadId" = "g1"."LeaderSquadId" +LEFT JOIN "Gears" AS "g1" ON "g0"."Nickname" IS "g1"."LeaderNickname" AND "g0"."SquadId" = "g1"."LeaderSquadId" ORDER BY "t"."Id", "g0"."Nickname", "g0"."SquadId", "g1"."Nickname" """); } @@ -6731,7 +6724,7 @@ public override async Task Projecting_property_converted_to_nullable_into_member SELECT "g"."Nickname" FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" -WHERE CAST(strftime('%m', "t"."IssueDate") AS INTEGER) <> 5 OR "t"."IssueDate" IS NULL +WHERE CAST(strftime('%m', "t"."IssueDate") AS INTEGER) IS NOT 5 ORDER BY "g"."Nickname" """); } @@ -6767,7 +6760,7 @@ LEFT JOIN ( WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" LEFT JOIN "Gears" AS "g" ON "l0"."DefeatedByNickname" = "g"."Nickname" AND "l0"."DefeatedBySquadId" = "g"."SquadId" -LEFT JOIN "Gears" AS "g0" ON ("g"."Nickname" = "g0"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g0"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g0"."LeaderSquadId" +LEFT JOIN "Gears" AS "g0" ON "g"."Nickname" IS "g0"."LeaderNickname" AND "g"."SquadId" = "g0"."LeaderSquadId" ORDER BY "f"."Id", "l0"."Name", "g"."Nickname", "g"."SquadId", "g0"."Nickname" """); } @@ -6796,7 +6789,7 @@ public override async Task Contains_on_collection_of_nullable_byte_subquery(bool WHERE EXISTS ( SELECT 1 FROM "LocustLeaders" AS "l0" - WHERE "l0"."ThreatLevelNullableByte" = "l"."ThreatLevelNullableByte" OR ("l0"."ThreatLevelNullableByte" IS NULL AND "l"."ThreatLevelNullableByte" IS NULL)) + WHERE "l0"."ThreatLevelNullableByte" IS "l"."ThreatLevelNullableByte") """); } @@ -6933,7 +6926,7 @@ public override async Task Correlated_collections_basic_projecting_constant(bool LEFT JOIN ( SELECT 'BFG' AS "c", "w"."Id", "w"."OwnerFullName" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -7352,7 +7345,7 @@ public override async Task Select_comparison_with_null(bool async) """ @ammunitionType='1' (Nullable = true) -SELECT "w"."Id", "w"."AmmunitionType" = @ammunitionType AND "w"."AmmunitionType" IS NOT NULL AS "Cartridge" +SELECT "w"."Id", "w"."AmmunitionType" IS @ammunitionType AS "Cartridge" FROM "Weapons" AS "w" WHERE "w"."AmmunitionType" = @ammunitionType """, @@ -7374,7 +7367,7 @@ public override async Task OfTypeNav2(bool async) FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" LEFT JOIN "Cities" AS "c" ON "g"."AssignedCityName" = "c"."Name" -WHERE ("t"."Note" <> 'Foo' OR "t"."Note" IS NULL) AND "g"."Discriminator" = 'Officer' AND ("c"."Location" <> 'Bar' OR "c"."Location" IS NULL) +WHERE "t"."Note" IS NOT 'Foo' AND "g"."Discriminator" = 'Officer' AND "c"."Location" IS NOT 'Bar' """); } @@ -7389,7 +7382,7 @@ public override async Task Correlated_collections_basic_projection(bool async) LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."IsAutomatic" OR "w"."Name" <> 'foo' OR "w"."Name" IS NULL + WHERE "w"."IsAutomatic" OR "w"."Name" IS NOT 'foo' ) AS "w0" ON "g"."FullName" = "w0"."OwnerFullName" WHERE "g"."Nickname" <> 'Marcus' ORDER BY "g"."Nickname", "g"."SquadId" @@ -7496,7 +7489,7 @@ LEFT JOIN ( WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" LEFT JOIN "Gears" AS "g" ON "l0"."DefeatedByNickname" = "g"."Nickname" AND "l0"."DefeatedBySquadId" = "g"."SquadId" -LEFT JOIN "Gears" AS "g0" ON ("g"."Nickname" = "g0"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g0"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g0"."LeaderSquadId" +LEFT JOIN "Gears" AS "g0" ON "g"."Nickname" IS "g0"."LeaderNickname" AND "g"."SquadId" = "g0"."LeaderSquadId" ORDER BY "f"."Id", "l0"."Name", "g"."Nickname", "g"."SquadId", "g0"."Nickname" """); } @@ -7617,7 +7610,7 @@ LEFT JOIN ( WHERE "l"."Discriminator" = 'LocustCommander' ) AS "l0" ON "f"."CommanderName" = "l0"."Name" LEFT JOIN "Gears" AS "g" ON "l0"."DefeatedByNickname" = "g"."Nickname" AND "l0"."DefeatedBySquadId" = "g"."SquadId" -LEFT JOIN "Gears" AS "g0" ON ("g"."Nickname" = "g0"."LeaderNickname" OR ("g"."Nickname" IS NULL AND "g0"."LeaderNickname" IS NULL)) AND "g"."SquadId" = "g0"."LeaderSquadId" +LEFT JOIN "Gears" AS "g0" ON "g"."Nickname" IS "g0"."LeaderNickname" AND "g"."SquadId" = "g0"."LeaderSquadId" ORDER BY "f"."Id", "l0"."Name", "g"."Nickname", "g"."SquadId", "g0"."Nickname" """); } @@ -7712,7 +7705,7 @@ LEFT JOIN ( LEFT JOIN ( SELECT "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Weapons" AS "w" - WHERE "w"."Name" <> 'Bar' OR "w"."Name" IS NULL + WHERE "w"."Name" IS NOT 'Bar' ) AS "w0" ON "g0"."FullName" = "w0"."OwnerFullName" WHERE "g0"."FullName" <> 'Foo' ) AS "s" ON "g"."Nickname" = "s"."LeaderNickname" AND "g"."SquadId" = "s"."LeaderSquadId" @@ -7745,7 +7738,7 @@ public override async Task Select_Where_Navigation_Scalar_Equals_Navigation_Scal CROSS JOIN "Tags" AS "t0" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" LEFT JOIN "Gears" AS "g0" ON "t0"."GearNickName" = "g0"."Nickname" AND "t0"."GearSquadId" = "g0"."SquadId" -WHERE "g"."Nickname" = "g0"."Nickname" OR ("g"."Nickname" IS NULL AND "g0"."Nickname" IS NULL) +WHERE "g"."Nickname" IS "g0"."Nickname" """); } @@ -7855,7 +7848,7 @@ public override async Task Select_Where_Navigation_Equals_Navigation(bool async) CROSS JOIN "Tags" AS "t0" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" LEFT JOIN "Gears" AS "g0" ON "t0"."GearNickName" = "g0"."Nickname" AND "t0"."GearSquadId" = "g0"."SquadId" -WHERE ("g"."Nickname" = "g0"."Nickname" OR ("g"."Nickname" IS NULL AND "g0"."Nickname" IS NULL)) AND ("g"."SquadId" = "g0"."SquadId" OR ("g"."SquadId" IS NULL AND "g0"."SquadId" IS NULL)) +WHERE "g"."Nickname" IS "g0"."Nickname" AND "g"."SquadId" IS "g0"."SquadId" """); } @@ -7894,7 +7887,7 @@ public override async Task Optional_navigation_type_compensation_works_with_proj SELECT "g"."SquadId" FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' """); } @@ -7976,7 +7969,7 @@ public override async Task Optional_navigation_type_compensation_works_with_list SELECT "g"."SquadId", "g"."SquadId" + 1 FROM "Tags" AS "t" LEFT JOIN "Gears" AS "g" ON "t"."GearNickName" = "g"."Nickname" AND "t"."GearSquadId" = "g"."SquadId" -WHERE "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'K.I.A.' ORDER BY "t"."Note" """); } @@ -7988,7 +7981,7 @@ public override async Task Projecting_property_converted_to_nullable_with_condit AssertSql( """ SELECT CASE - WHEN "t"."Note" <> 'K.I.A.' OR "t"."Note" IS NULL THEN CASE + WHEN "t"."Note" IS NOT 'K.I.A.' THEN CASE WHEN "t"."GearNickName" IS NOT NULL THEN "g"."SquadId" END ELSE -1 @@ -8021,7 +8014,7 @@ public override async Task Count_with_optional_navigation_is_translated_to_sql(b SELECT COUNT(*) FROM "Gears" AS "g" LEFT JOIN "Tags" AS "t" ON "g"."Nickname" = "t"."GearNickName" AND "g"."SquadId" = "t"."GearSquadId" -WHERE "t"."Note" <> 'Foo' OR "t"."Note" IS NULL +WHERE "t"."Note" IS NOT 'Foo' """); } @@ -8303,7 +8296,7 @@ public override async Task Navigation_based_on_complex_expression6(bool async) AssertSql( """ -SELECT "l2"."Name" = 'Queen Myrrah' AND "l2"."Name" IS NOT NULL, "l2"."Name", "l2"."Discriminator", "l2"."LocustHordeId", "l2"."ThreatLevel", "l2"."ThreatLevelByte", "l2"."ThreatLevelNullableByte", "l2"."DefeatedByNickname", "l2"."DefeatedBySquadId", "l2"."HighCommandId", "l0"."Name", "l0"."Discriminator", "l0"."LocustHordeId", "l0"."ThreatLevel", "l0"."ThreatLevelByte", "l0"."ThreatLevelNullableByte", "l0"."DefeatedByNickname", "l0"."DefeatedBySquadId", "l0"."HighCommandId" +SELECT "l2"."Name" IS 'Queen Myrrah', "l2"."Name", "l2"."Discriminator", "l2"."LocustHordeId", "l2"."ThreatLevel", "l2"."ThreatLevelByte", "l2"."ThreatLevelNullableByte", "l2"."DefeatedByNickname", "l2"."DefeatedBySquadId", "l2"."HighCommandId", "l0"."Name", "l0"."Discriminator", "l0"."LocustHordeId", "l0"."ThreatLevel", "l0"."ThreatLevelByte", "l0"."ThreatLevelNullableByte", "l0"."DefeatedByNickname", "l0"."DefeatedBySquadId", "l0"."HighCommandId" FROM "Factions" AS "f" CROSS JOIN ( SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId" @@ -8691,7 +8684,7 @@ SELECT COALESCE(SUM(length("c"."Location")), 0) UNION ALL SELECT "g4"."Nickname" FROM "Gears" AS "g4" - ) AND ("s"."Name" = "s0"."Name" OR ("s"."Name" IS NULL AND "s0"."Name" IS NULL))) AS "SumOfLengths" + ) AND "s"."Name" IS "s0"."Name") AS "SumOfLengths" FROM "Gears" AS "g" INNER JOIN "Squads" AS "s" ON "g"."SquadId" = "s"."Id" WHERE 'Marcus' IN ( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs index 2ad71f39ae9..441080ada88 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs @@ -32,7 +32,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."NullableIntA" = "e"."IntB" AND "e"."NullableIntA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS "e"."IntB" AS "X" FROM "Entities1" AS "e" """, // @@ -43,7 +43,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."IntA" = "e"."NullableIntB" AND "e"."NullableIntB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."IntA" IS "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // @@ -54,14 +54,14 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableIntA" = "e"."NullableIntB" OR ("e"."NullableIntA" IS NULL AND "e"."NullableIntB" IS NULL) +WHERE "e"."NullableIntA" IS "e"."NullableIntB" """, // """ @@ -76,36 +76,36 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."NullableIntA" <> "e"."IntB" OR "e"."NullableIntA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS NOT "e"."IntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableIntA" <> "e"."IntB" OR "e"."NullableIntA" IS NULL +WHERE "e"."NullableIntA" IS NOT "e"."IntB" """, // """ -SELECT "e"."Id", "e"."IntA" <> "e"."NullableIntB" OR "e"."NullableIntB" IS NULL AS "X" +SELECT "e"."Id", "e"."IntA" IS NOT "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."IntA" <> "e"."NullableIntB" OR "e"."NullableIntB" IS NULL +WHERE "e"."IntA" IS NOT "e"."NullableIntB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS NOT "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("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) +WHERE "e"."NullableIntA" IS NOT "e"."NullableIntB" """, // """ @@ -120,36 +120,36 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."NullableIntA" <> "e"."IntB" OR "e"."NullableIntA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS NOT "e"."IntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableIntA" <> "e"."IntB" OR "e"."NullableIntA" IS NULL +WHERE "e"."NullableIntA" IS NOT "e"."IntB" """, // """ -SELECT "e"."Id", "e"."IntA" <> "e"."NullableIntB" OR "e"."NullableIntB" IS NULL AS "X" +SELECT "e"."Id", "e"."IntA" IS NOT "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."IntA" <> "e"."NullableIntB" OR "e"."NullableIntB" IS NULL +WHERE "e"."IntA" IS NOT "e"."NullableIntB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS NOT "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE ("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) +WHERE "e"."NullableIntA" IS NOT "e"."NullableIntB" """, // """ @@ -164,7 +164,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."NullableIntA" = "e"."IntB" AND "e"."NullableIntA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS "e"."IntB" AS "X" FROM "Entities1" AS "e" """, // @@ -175,7 +175,7 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", "e"."IntA" = "e"."NullableIntB" AND "e"."NullableIntB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."IntA" IS "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // @@ -186,14 +186,14 @@ public override async Task Rewrite_compare_int_with_int(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableIntA" IS "e"."NullableIntB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableIntA" = "e"."NullableIntB" OR ("e"."NullableIntA" IS NULL AND "e"."NullableIntB" IS NULL) +WHERE "e"."NullableIntA" IS "e"."NullableIntB" """); } @@ -214,7 +214,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -236,7 +236,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", (NOT ("e"."BoolA")) IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -247,7 +247,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -258,18 +258,18 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."NullableBoolB" AS "X" 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" IS "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -280,14 +280,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE (NOT ("e"."NullableBoolA")) IS "e"."NullableBoolB" """, // """ @@ -302,7 +302,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // @@ -324,7 +324,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -335,7 +335,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS (NOT ("e"."BoolB")) AS "X" FROM "Entities1" AS "e" """, // @@ -346,18 +346,18 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" IS (NOT ("e"."NullableBoolB")) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -368,14 +368,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."NullableBoolB" AS "X" 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" IS "e"."NullableBoolB" """, // """ @@ -390,14 +390,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT "e"."NullableBoolB" """, // """ @@ -412,58 +412,58 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", (NOT ("e"."BoolA")) IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE (NOT ("e"."BoolA")) IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -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) +WHERE "e"."NullableBoolA" IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE (NOT ("e"."NullableBoolA")) IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS NOT "e"."NullableBoolB" AS "X" 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 (NOT ("e"."NullableBoolA")) IS NOT "e"."NullableBoolB" """, // """ @@ -478,14 +478,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT (NOT ("e"."NullableBoolB")) """, // """ @@ -500,58 +500,58 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT (NOT ("e"."BoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT (NOT ("e"."BoolB")) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT (NOT ("e"."NullableBoolB")) AS "X" 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" IS NOT (NOT ("e"."NullableBoolB")) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -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) +WHERE "e"."NullableBoolA" IS NOT "e"."NullableBoolB" """, // """ @@ -566,14 +566,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = (NOT ("e"."NullableBoolB")) OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT "e"."NullableBoolB" """, // """ @@ -588,58 +588,58 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", (NOT ("e"."BoolA")) IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE (NOT ("e"."BoolA")) IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = (NOT ("e"."BoolB")) OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -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) +WHERE "e"."NullableBoolA" IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE (NOT ("e"."NullableBoolA")) IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS NOT "e"."NullableBoolB" AS "X" 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 (NOT ("e"."NullableBoolA")) IS NOT "e"."NullableBoolB" """, // """ @@ -654,14 +654,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT (NOT ("e"."NullableBoolB")) """, // """ @@ -676,58 +676,58 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."BoolA")) = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +WHERE "e"."BoolA" IS NOT "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT (NOT ("e"."BoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT (NOT ("e"."BoolB")) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT (NOT ("e"."NullableBoolB")) AS "X" 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" IS NOT (NOT ("e"."NullableBoolB")) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."NullableBoolA")) = "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE "e"."NullableBoolA" IS NOT "e"."BoolB" """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS NOT "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -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) +WHERE "e"."NullableBoolA" IS NOT "e"."NullableBoolB" """, // """ @@ -742,7 +742,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -764,7 +764,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", (NOT ("e"."BoolA")) IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -775,7 +775,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -786,18 +786,18 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."NullableBoolB" AS "X" 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" IS "e"."NullableBoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -808,14 +808,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", (NOT ("e"."NullableBoolA")) IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE (NOT ("e"."NullableBoolA")) = "e"."NullableBoolB" OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE (NOT ("e"."NullableBoolA")) IS "e"."NullableBoolB" """, // """ @@ -830,7 +830,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // @@ -852,7 +852,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" IS "e"."NullableBoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -863,7 +863,7 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS (NOT ("e"."BoolB")) AS "X" FROM "Entities1" AS "e" """, // @@ -874,18 +874,18 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS (NOT ("e"."NullableBoolB")) AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = (NOT ("e"."NullableBoolB")) OR ("e"."NullableBoolA" IS NULL AND "e"."NullableBoolB" IS NULL) +WHERE "e"."NullableBoolA" IS (NOT ("e"."NullableBoolB")) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // @@ -896,14 +896,14 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", ("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) AS "X" +SELECT "e"."Id", "e"."NullableBoolA" IS "e"."NullableBoolB" AS "X" 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" IS "e"."NullableBoolB" """); } @@ -951,7 +951,7 @@ public override async Task Join_uses_csharp_semantics_for_anon_objects(bool asyn """ SELECT "e"."Id" AS "Id1", "e0"."Id" AS "Id2", "e"."NullableIntA", "e0"."NullableIntB" FROM "Entities1" AS "e" -INNER JOIN "Entities2" AS "e0" ON "e"."NullableIntA" = "e0"."NullableIntB" OR ("e"."NullableIntA" IS NULL AND "e0"."NullableIntB" IS NULL) +INNER JOIN "Entities2" AS "e0" ON "e"."NullableIntA" IS "e0"."NullableIntB" """); } @@ -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" = (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" + WHEN "e"."NullableBoolA" IS NOT "e"."NullableBoolB" THEN "e"."BoolB" ELSE "e"."BoolC" END = "e"."BoolA" """, @@ -983,10 +983,10 @@ WHERE CASE FROM "Entities1" AS "e" WHERE 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) + WHEN "e"."BoolA" THEN "e"."NullableBoolA" IS NOT "e"."NullableBoolB" ELSE "e"."BoolC" END)) = "e"."BoolB" THEN "e"."BoolA" - ELSE "e"."NullableBoolB" = "e"."NullableBoolC" OR ("e"."NullableBoolB" IS NULL AND "e"."NullableBoolC" IS NULL) + ELSE "e"."NullableBoolB" IS "e"."NullableBoolC" END """, // @@ -1085,7 +1085,7 @@ public override async Task Null_semantics_contains_nullable_item_with_nullable_s WHERE EXISTS ( SELECT 1 FROM "Entities2" AS "e0" - WHERE "e0"."NullableStringA" = "e"."NullableStringB" OR ("e0"."NullableStringA" IS NULL AND "e"."NullableStringB" IS NULL)) + WHERE "e0"."NullableStringA" IS "e"."NullableStringB") """, // """ @@ -1094,7 +1094,7 @@ SELECT 1 WHERE NOT EXISTS ( SELECT 1 FROM "Entities2" AS "e0" - WHERE "e0"."NullableStringA" = "e"."NullableStringB" OR ("e0"."NullableStringA" IS NULL AND "e"."NullableStringB" IS NULL)) + WHERE "e0"."NullableStringA" IS "e"."NullableStringB") """); } @@ -1140,11 +1140,7 @@ SELECT CASE WHEN "e"."StringA" = 'Foo' THEN 3 WHEN "e"."StringB" = 'Foo' THEN 2 WHEN "e"."StringC" = 'Foo' THEN 3 -END = 2 AND CASE - WHEN "e"."StringA" = 'Foo' THEN 3 - WHEN "e"."StringB" = 'Foo' THEN 2 - WHEN "e"."StringC" = 'Foo' THEN 3 -END IS NOT NULL +END IS 2 FROM "Entities1" AS "e" ORDER BY "e"."Id" """); @@ -1160,11 +1156,7 @@ SELECT CASE WHEN "e"."StringA" = 'Foo' THEN 3 WHEN "e"."StringB" = 'Foo' THEN 2 WHEN "e"."StringC" = 'Foo' THEN 3 -END = 3 AND CASE - WHEN "e"."StringA" = 'Foo' THEN 3 - WHEN "e"."StringB" = 'Foo' THEN 2 - WHEN "e"."StringC" = 'Foo' THEN 3 -END IS NOT NULL +END IS 3 FROM "Entities1" AS "e" ORDER BY "e"."Id" """); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 36707983506..d2a11fcf8d3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -1068,7 +1068,7 @@ public override async Task Nullable_reference_column_collection_index_equals_nul """ SELECT "p"."Id", "p"."Bool", "p"."Bools", "p"."DateTime", "p"."DateTimes", "p"."Enum", "p"."Enums", "p"."Int", "p"."Ints", "p"."NullableInt", "p"."NullableInts", "p"."NullableString", "p"."NullableStrings", "p"."NullableWrappedId", "p"."NullableWrappedIdWithNullableComparer", "p"."String", "p"."Strings", "p"."WrappedId" FROM "PrimitiveCollectionsEntity" AS "p" -WHERE "p"."NullableStrings" ->> 2 = "p"."NullableString" OR ("p"."NullableStrings" ->> 2 IS NULL AND "p"."NullableString" IS NULL) +WHERE "p"."NullableStrings" ->> 2 IS "p"."NullableString" """); }