From 4185501e1ac07c2b02e1c4a95de20c53a0d096bf Mon Sep 17 00:00:00 2001 From: Maurycy Markowski Date: Tue, 14 Jan 2025 01:06:51 -0800 Subject: [PATCH 1/2] [release/9.0-staging] Fix to #35393 - GroupJoin in EF Core 9 Returns Null for Joined Entities Fixes #35393 Description In EF9 we refactored some optimizations we performed on generated SQL - we are now applying them earlier (as part of SqlExpressionFactory. However, one of those optimizations is only correct for non-nullable arguments, and at the time we apply them we don't have full nullability information. Fix is to only apply this optimization when we know the argument is non-nullable. Customer impact Data corruption. Queries comparing nullable boolean property to a constant (true/false) produced incorrect results (data corruption). Workaround is to rewrite the query to add missing null checks, but this is not intuitive at all. How found Customer report on 9.0.0 Regression Yes, from 8.0. Testing Added tests for the scenarios affected as well as test that brute-forces all combinations of comparisons between nullable arguments in variety of scenarios. Risk Low, we are just removing the optimization that was incorrect. After removal, the queries produced are the same as in EF8. Quirk added, just in case. --- .../Query/SqlExpressionFactory.cs | 30 +- .../Query/SqlNullabilityProcessor.cs | 5 +- .../Query/NullSemanticsQueryTestBase.cs | 73 +- .../Query/NorthwindJoinQueryTestBase.cs | 18 + .../Query/GearsOfWarQuerySqlServerTest.cs | 6 +- .../Query/NorthwindJoinQuerySqlServerTest.cs | 16 + .../Query/NullSemanticsQuerySqlServerTest.cs | 1100 ++++++++++++++--- .../Query/TPCGearsOfWarQuerySqlServerTest.cs | 6 +- .../Query/TPTGearsOfWarQuerySqlServerTest.cs | 6 +- .../TemporalGearsOfWarQuerySqlServerTest.cs | 6 +- .../Query/GearsOfWarQuerySqliteTest.cs | 6 +- .../Query/NorthwindJoinQuerySqliteTest.cs | 6 + .../Query/NullSemanticsQuerySqliteTest.cs | 864 +++++++++++-- 13 files changed, 1860 insertions(+), 282 deletions(-) diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 47f94f1d78b..31553d0e9db 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -9,6 +9,9 @@ namespace Microsoft.EntityFrameworkCore.Query; /// public class SqlExpressionFactory : ISqlExpressionFactory { + private static readonly bool UseOldBehavior35393 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35393", out var enabled35393) && enabled35393; + private readonly IRelationalTypeMappingSource _typeMappingSource; private readonly RelationalTypeMapping _boolTypeMapping; @@ -660,20 +663,45 @@ private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpressi SqlBinaryExpression { OperatorType: ExpressionType.OrElse } binary => AndAlso(Not(binary.Left), Not(binary.Right)), - // use equality where possible + // use equality where possible - we can only do this when we know a is not null + // at this point we are limited to constants, parameters and columns + // see issue #35393 // !(a == true) -> a == false // !(a == false) -> a == true SqlBinaryExpression { OperatorType: ExpressionType.Equal, Right: SqlConstantExpression { Value: bool } } binary + when UseOldBehavior35393 + => Equal(binary.Left, Not(binary.Right)), + + SqlBinaryExpression + { + OperatorType: ExpressionType.Equal, + Right: SqlConstantExpression { Value: bool }, + Left: SqlConstantExpression { Value: bool } + or SqlParameterExpression { IsNullable: false } + or ColumnExpression { IsNullable: false } + } binary => Equal(binary.Left, Not(binary.Right)), // !(true == a) -> false == a // !(false == a) -> true == a SqlBinaryExpression { OperatorType: ExpressionType.Equal, Left: SqlConstantExpression { Value: bool } } binary + when UseOldBehavior35393 + => Equal(Not(binary.Left), binary.Right), + + SqlBinaryExpression + { + OperatorType: ExpressionType.Equal, + Left: SqlConstantExpression { Value: bool }, + Right: SqlConstantExpression { Value: bool } + or SqlParameterExpression { IsNullable: false } + or ColumnExpression { IsNullable: false } + } binary => Equal(Not(binary.Left), binary.Right), // !(a == b) -> a != b SqlBinaryExpression { OperatorType: ExpressionType.Equal } sqlBinaryOperand => NotEqual( sqlBinaryOperand.Left, sqlBinaryOperand.Right), + // !(a != b) -> a == b SqlBinaryExpression { OperatorType: ExpressionType.NotEqual } sqlBinaryOperand => Equal( sqlBinaryOperand.Left, sqlBinaryOperand.Right), diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 407826342f2..95b79bfe9a7 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -19,6 +19,9 @@ namespace Microsoft.EntityFrameworkCore.Query; /// public class SqlNullabilityProcessor { + private static readonly bool UseOldBehavior35393 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35393", out var enabled35393) && enabled35393; + private readonly List _nonNullableColumns; private readonly List _nullValueColumns; private readonly ISqlExpressionFactory _sqlExpressionFactory; @@ -1343,7 +1346,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 diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs index 4ac99509883..629ec36e194 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs @@ -92,6 +92,7 @@ public virtual async Task Rewrite_compare_int_with_int(bool async) public virtual async Task Rewrite_compare_bool_with_bool(bool async) { var bools = new[] { false, true }; + var onetwothree = new[] { 1, 2, 3 }; foreach (var neq in bools) { @@ -99,15 +100,18 @@ public virtual async Task Rewrite_compare_bool_with_bool(bool async) { foreach (var negateB in bools) { - foreach (var nullableA in bools) + foreach (var nullableA in onetwothree) { foreach (var negateA in bools) { - foreach (var nullableB in bools) + foreach (var nullableB in onetwothree) { + // filter out tests comparing two constants + if (nullableA == 3 && nullableB == 3) continue; + var queryBuilder = (ISetSource ss) => { - var data = nullableA + var data = nullableA == 2 ? ss.Set().Select( e => new { @@ -116,16 +120,25 @@ public virtual async Task Rewrite_compare_bool_with_bool(bool async) e.BoolB, e.NullableBoolB }) - : ss.Set().Select( - e => new - { - e.Id, - A = (bool?)e.BoolA, - e.BoolB, - e.NullableBoolB - }); - - var query = nullableB + : nullableA == 1 + ? ss.Set().Select( + e => new + { + e.Id, + A = (bool?)e.BoolA, + e.BoolB, + e.NullableBoolB + }) + : ss.Set().Select( + e => new + { + e.Id, + A = (bool?)true, + e.BoolB, + e.NullableBoolB + }); + + var query = nullableB == 2 ? data.Select( e => new { @@ -133,13 +146,21 @@ public virtual async Task Rewrite_compare_bool_with_bool(bool async) e.A, B = e.NullableBoolB }) - : data.Select( - e => new - { - e.Id, - e.A, - B = (bool?)e.BoolB - }); + : nullableB == 1 + ? data.Select( + e => new + { + e.Id, + e.A, + B = (bool?)e.BoolB + }) + : data.Select( + e => new + { + e.Id, + e.A, + B = (bool?)true + }); query = negateA ? query.Select( @@ -2462,6 +2483,18 @@ await AssertQueryScalar( ss => ss.Set().Where(e => true).Select(e => e.Id)); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Compare_constant_true_to_expression_which_evaluates_to_null(bool async) + { + var prm = default(bool?); + + await AssertQueryScalar( + async, + ss => ss.Set().Where(x => x.NullableBoolA != null + && !object.Equals(true, x.NullableBoolA == null ? null : prm)).Select(x => x.Id)); + } + // We can't client-evaluate Like (for the expected results). // However, since the test data has no LIKE wildcards, it effectively functions like equality - except that 'null like null' returns // false instead of true. So we have this "lite" implementation which doesn't support wildcards. diff --git a/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs index 6f3350b748f..571d9fcbac9 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindJoinQueryTestBase.cs @@ -654,6 +654,24 @@ join o in ss.Set().OrderBy(o => o.OrderID).Take(100) on c.CustomerID equa from o in lo.Where(x => x.CustomerID.StartsWith("A")) select new { c.CustomerID, o.OrderID }); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupJoin_on_true_equal_true(bool async) + => AssertQuery( + async, + ss => ss.Set().GroupJoin( + ss.Set(), + x => true, + x => true, + (c, g) => new { c, g }) + .Select(x => new { x.c.CustomerID, Orders = x.g }), + elementSorter: e => e.CustomerID, + elementAsserter: (e, a) => + { + Assert.Equal(e.CustomerID, a.CustomerID); + AssertCollection(e.Orders, a.Orders, elementSorter: ee => ee.OrderID); + }); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Inner_join_with_tautology_predicate_converts_to_cross_join(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index f7569611bb0..cae4816b1ae 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -5021,7 +5021,7 @@ INNER JOIN ( FROM [Factions] AS [f] WHERE [f].[Name] = N'Swarm' ) AS [f0] ON [l].[Name] = [f0].[CommanderName] -WHERE [f0].[Eradicated] = CAST(0 AS bit) OR [f0].[Eradicated] IS NULL +WHERE [f0].[Eradicated] <> CAST(1 AS bit) OR [f0].[Eradicated] IS NULL """); } @@ -5038,7 +5038,7 @@ LEFT JOIN ( FROM [Factions] AS [f] WHERE [f].[Name] = N'Swarm' ) AS [f0] ON [l].[Name] = [f0].[CommanderName] -WHERE [f0].[Eradicated] = CAST(0 AS bit) OR [f0].[Eradicated] IS NULL +WHERE [f0].[Eradicated] <> CAST(1 AS bit) OR [f0].[Eradicated] IS NULL """); } @@ -7592,7 +7592,7 @@ FROM [LocustLeaders] AS [l] INNER JOIN [Factions] AS [f] ON [l].[Name] = [f].[CommanderName] WHERE CASE WHEN [f].[Name] = N'Locust' THEN CAST(1 AS bit) -END = CAST(0 AS bit) OR CASE +END <> CAST(1 AS bit) OR CASE WHEN [f].[Name] = N'Locust' THEN CAST(1 AS bit) END IS NULL """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs index 48c3758e51a..bf95109abca 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindJoinQuerySqlServerTest.cs @@ -992,6 +992,22 @@ ORDER BY [o].[OrderID] """); } + public override async Task GroupJoin_on_true_equal_true(bool async) + { + await base.GroupJoin_on_true_equal_true(async); + + AssertSql( + """ +SELECT [c].[CustomerID], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] +FROM [Customers] AS [c] +OUTER APPLY ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] + FROM [Orders] AS [o] +) AS [o0] +ORDER BY [c].[CustomerID] +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs index 2581e0a3baa..f0e488b7a65 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs @@ -265,33 +265,30 @@ FROM [Entities1] AS [e] """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +SELECT [e].[Id], [e].[BoolA] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolA] = CAST(1 AS bit) """, // """ -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] +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] <> [e].[BoolB] """, // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + 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] @@ -300,26 +297,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] +WHERE [e].[BoolA] <> [e].[NullableBoolB] """, // """ -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] +SELECT [e].[Id], ~[e].[BoolA] 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].[BoolA] = CAST(0 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] <> [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + 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] @@ -328,12 +322,12 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +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) + 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] @@ -342,23 +336,26 @@ 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) """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = CAST(1 AS bit) 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].[BoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = CAST(1 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + 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] @@ -367,23 +364,26 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[NullableBoolA] <> [e].[BoolB] """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +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].[BoolA] = [e].[BoolB] +WHERE [e].[NullableBoolA] <> [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] <> CAST(1 AS bit) AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -392,26 +392,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] +WHERE [e].[NullableBoolA] = CAST(0 AS bit) """, // """ -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] +SELECT [e].[Id], [e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[BoolB] = CAST(1 AS bit) """, // """ 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) + WHEN CAST(1 AS bit) = [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] @@ -420,26 +417,23 @@ 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].[NullableBoolB] = CAST(1 AS bit) """, // """ -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] +SELECT [e].[Id], ~[e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] +WHERE [e].[BoolB] = CAST(0 AS bit) """, // """ 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) + WHEN CAST(0 AS bit) = [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] @@ -448,7 +442,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 CAST(0 AS bit) = [e].[NullableBoolB] """, // """ @@ -464,7 +458,7 @@ WHERE [e].[BoolA] <> [e].[BoolB] // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + 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] @@ -473,37 +467,34 @@ 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] """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +SELECT [e].[Id], ~[e].[BoolA] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[BoolB] +WHERE [e].[BoolA] = CAST(0 AS bit) """, // """ -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] +SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) 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] = [e].[BoolB] """, // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + 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] @@ -512,26 +503,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[BoolA] = [e].[NullableBoolB] """, // """ -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] +SELECT [e].[Id], [e].[BoolA] 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].[BoolA] = CAST(1 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + 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] @@ -540,12 +528,12 @@ 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] """, // """ 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) + 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] @@ -554,23 +542,26 @@ 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 AND [e].[NullableBoolB] IS NULL) """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] = CAST(0 AS bit) 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].[BoolA] = [e].[BoolB] +WHERE [e].[NullableBoolA] = CAST(0 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + 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] @@ -579,23 +570,26 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[NullableBoolA] = [e].[BoolB] """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +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].[BoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] = [e].[NullableBoolB] OR ([e].[NullableBoolA] IS NULL AND [e].[NullableBoolB] IS NULL) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] <> CAST(0 AS bit) AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -604,26 +598,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[NullableBoolA] <> CAST(0 AS bit) """, // """ -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] +SELECT [e].[Id], ~[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].[BoolB] = CAST(0 AS bit) """, // """ 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) + WHEN CAST(1 AS bit) <> [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] @@ -632,26 +623,23 @@ 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].[NullableBoolB] = CAST(0 AS bit) """, // """ -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] +SELECT [e].[Id], [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].[BoolB] = CAST(1 AS bit) """, // """ 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) + WHEN CAST(0 AS bit) <> [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] @@ -660,7 +648,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 CAST(0 AS bit) <> [e].[NullableBoolB] """, // """ @@ -686,6 +674,17 @@ 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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(0 AS bit) """, // """ @@ -711,6 +710,17 @@ 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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(1 AS bit) """, // """ @@ -743,7 +753,7 @@ FROM [Entities1] AS [e] // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] <> CAST(1 AS bit) OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -752,12 +762,12 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL +WHERE [e].[NullableBoolA] <> CAST(1 AS bit) 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) + 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] @@ -766,23 +776,26 @@ 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].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +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].[BoolA] = [e].[BoolB] +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].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] = CAST(1 AS bit) OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -791,23 +804,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE [e].[NullableBoolA] = CAST(1 AS bit) OR [e].[NullableBoolA] IS NULL """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +SELECT [e].[Id], ~[e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[BoolB] +WHERE [e].[BoolB] = CAST(0 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) + WHEN CAST(1 AS bit) <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -816,26 +829,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +WHERE CAST(1 AS bit) <> [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] +SELECT [e].[Id], [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].[BoolB] = CAST(1 AS bit) """, // """ 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) + WHEN CAST(0 AS bit) <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -844,26 +854,23 @@ 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 CAST(0 AS bit) <> [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] +SELECT [e].[Id], ~([e].[BoolA] ^ [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].[BoolA] = [e].[BoolB] """, // """ 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) + 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] @@ -872,62 +879,59 @@ 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].[BoolA] = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +SELECT [e].[Id], [e].[BoolA] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[BoolB] +WHERE [e].[BoolA] = CAST(1 AS bit) """, // """ -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] +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] +WHERE [e].[BoolA] <> [e].[BoolB] """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +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].[BoolB] +WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL """, // """ -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] +SELECT [e].[Id], ~[e].[BoolA] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[BoolA] = CAST(0 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[NullableBoolA] = [e].[BoolB] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + 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] @@ -936,12 +940,12 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] +WHERE [e].[NullableBoolA] = [e].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ 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) + 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] @@ -950,12 +954,12 @@ 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 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] AND [e].[NullableBoolA] IS NOT NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] <> CAST(0 AS bit) OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -964,12 +968,12 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[NullableBoolA] <> CAST(0 AS bit) OR [e].[NullableBoolA] IS NULL """, // """ 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) + 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] @@ -978,23 +982,26 @@ 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].[BoolB] OR [e].[NullableBoolA] IS NULL """, // """ -SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] +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].[BoolA] <> [e].[BoolB] +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].[BoolA] <> [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + WHEN [e].[NullableBoolA] = CAST(0 AS bit) OR [e].[NullableBoolA] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -1003,23 +1010,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] <> [e].[NullableBoolB] +WHERE [e].[NullableBoolA] = CAST(0 AS bit) OR [e].[NullableBoolA] IS NULL """, // """ -SELECT [e].[Id], ~([e].[BoolA] ^ [e].[BoolB]) AS [X] +SELECT [e].[Id], [e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[BoolB] +WHERE [e].[BoolB] = CAST(1 AS bit) """, // """ SELECT [e].[Id], CASE - WHEN [e].[BoolA] = [e].[NullableBoolB] AND [e].[NullableBoolB] IS NOT NULL THEN CAST(1 AS bit) + WHEN CAST(1 AS bit) = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -1028,26 +1035,23 @@ FROM [Entities1] AS [e] """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] +WHERE CAST(1 AS bit) = [e].[NullableBoolB] OR [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] +SELECT [e].[Id], ~[e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] <> [e].[BoolB] +WHERE [e].[BoolB] = CAST(0 AS bit) """, // """ 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) + WHEN CAST(0 AS bit) = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [X] FROM [Entities1] AS [e] @@ -1056,26 +1060,23 @@ 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 CAST(0 AS bit) = [e].[NullableBoolB] OR [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] +SELECT [e].[Id], [e].[BoolA] ^ [e].[BoolB] AS [X] FROM [Entities1] AS [e] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[NullableBoolA] = [e].[BoolB] +WHERE [e].[BoolA] <> [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) + 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] @@ -1084,37 +1085,806 @@ 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( +WHERE [e].[BoolA] <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // """ -SELECT [e].[Id] +SELECT [e].[Id], ~[e].[BoolA] AS [X] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[BoolB] """, // """ SELECT [e].[Id] FROM [Entities1] AS [e] -WHERE [e].[BoolA] = [e].[NullableBoolB] +WHERE [e].[BoolA] = CAST(0 AS bit) """, // """ -SELECT [e].[Id] +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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(1 AS bit) +""", + // + """ +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] <> CAST(1 AS bit) 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] <> CAST(1 AS bit) OR [e].[NullableBoolA] 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] = CAST(1 AS bit) 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] = CAST(1 AS bit) OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], ~[e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(1 AS bit) <> [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 CAST(1 AS bit) <> [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(1 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(0 AS bit) <> [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 CAST(0 AS bit) <> [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], [e].[BoolA] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(1 AS bit) +""", + // + """ +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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(0 AS bit) +""", + // + """ +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] <> CAST(0 AS bit) 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] <> CAST(0 AS bit) OR [e].[NullableBoolA] 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] = CAST(0 AS bit) 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] = CAST(0 AS bit) OR [e].[NullableBoolA] IS NULL +""", + // + """ +SELECT [e].[Id], [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(1 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(1 AS bit) = [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 CAST(1 AS bit) = [e].[NullableBoolB] OR [e].[NullableBoolB] IS NULL +""", + // + """ +SELECT [e].[Id], ~[e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(0 AS bit) = [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 CAST(0 AS bit) = [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] 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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(1 AS bit) +""", + // + """ +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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(0 AS bit) +""", + // + """ +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] = CAST(1 AS bit) 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] = CAST(1 AS bit) +""", + // + """ +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] <> CAST(1 AS bit) 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] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(1 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(1 AS bit) = [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].[NullableBoolB] = CAST(1 AS bit) +""", + // + """ +SELECT [e].[Id], ~[e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(0 AS bit) = [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 CAST(0 AS bit) = [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], ~[e].[BoolA] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(0 AS bit) +""", + // + """ +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] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolA] = CAST(1 AS bit) +""", + // + """ +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] = CAST(0 AS bit) 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] = CAST(0 AS bit) +""", + // + """ +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] -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) +""", + // + """ +SELECT [e].[Id], CASE + WHEN [e].[NullableBoolA] <> CAST(0 AS bit) 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] <> CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], ~[e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(1 AS bit) <> [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].[NullableBoolB] = CAST(0 AS bit) +""", + // + """ +SELECT [e].[Id], [e].[BoolB] AS [X] +FROM [Entities1] AS [e] +""", + // + """ +SELECT [e].[Id] +FROM [Entities1] AS [e] +WHERE [e].[BoolB] = CAST(1 AS bit) +""", + // + """ +SELECT [e].[Id], CASE + WHEN CAST(0 AS bit) <> [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 CAST(0 AS bit) <> [e].[NullableBoolB] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 0eca14b01d9..ee461d32d9c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -6824,7 +6824,7 @@ INNER JOIN ( FROM [LocustHordes] AS [l1] WHERE [l1].[Name] = N'Swarm' ) AS [l2] ON [u].[Name] = [l2].[CommanderName] -WHERE [l2].[Eradicated] = CAST(0 AS bit) OR [l2].[Eradicated] IS NULL +WHERE [l2].[Eradicated] <> CAST(1 AS bit) OR [l2].[Eradicated] IS NULL """); } @@ -6847,7 +6847,7 @@ LEFT JOIN ( FROM [LocustHordes] AS [l1] WHERE [l1].[Name] = N'Swarm' ) AS [l2] ON [u].[Name] = [l2].[CommanderName] -WHERE [l2].[Eradicated] = CAST(0 AS bit) OR [l2].[Eradicated] IS NULL +WHERE [l2].[Eradicated] <> CAST(1 AS bit) OR [l2].[Eradicated] IS NULL """); } @@ -10136,7 +10136,7 @@ FROM [LocustCommanders] AS [l0] INNER JOIN [LocustHordes] AS [l1] ON [u].[Name] = [l1].[CommanderName] WHERE CASE WHEN [l1].[Name] = N'Locust' THEN CAST(1 AS bit) -END = CAST(0 AS bit) OR CASE +END <> CAST(1 AS bit) OR CASE WHEN [l1].[Name] = N'Locust' THEN CAST(1 AS bit) END IS NULL """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index fb8d0803c80..076e6c19d97 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -5766,7 +5766,7 @@ FROM [Factions] AS [f] LEFT JOIN [LocustHordes] AS [l0] ON [f].[Id] = [l0].[Id] WHERE [l0].[Id] IS NOT NULL AND [f].[Name] = N'Swarm' ) AS [s] ON [l].[Name] = [s].[CommanderName] -WHERE [s].[Eradicated] = CAST(0 AS bit) OR [s].[Eradicated] IS NULL +WHERE [s].[Eradicated] <> CAST(1 AS bit) OR [s].[Eradicated] IS NULL """); } @@ -5786,7 +5786,7 @@ FROM [Factions] AS [f] LEFT JOIN [LocustHordes] AS [l0] ON [f].[Id] = [l0].[Id] WHERE [l0].[Id] IS NOT NULL AND [f].[Name] = N'Swarm' ) AS [s] ON [l].[Name] = [s].[CommanderName] -WHERE [s].[Eradicated] = CAST(0 AS bit) OR [s].[Eradicated] IS NULL +WHERE [s].[Eradicated] <> CAST(1 AS bit) OR [s].[Eradicated] IS NULL """); } @@ -8602,7 +8602,7 @@ WHERE [l0].[Id] IS NOT NULL ) AS [s] ON [l].[Name] = [s].[CommanderName] WHERE CASE WHEN [s].[Name] = N'Locust' THEN CAST(1 AS bit) -END = CAST(0 AS bit) OR CASE +END <> CAST(1 AS bit) OR CASE WHEN [s].[Name] = N'Locust' THEN CAST(1 AS bit) END IS NULL """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index 01ccc04db5a..ca649d80e12 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -2564,7 +2564,7 @@ SELECT CASE INNER JOIN [Factions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [f] ON [l].[Name] = [f].[CommanderName] WHERE CASE WHEN [f].[Name] = N'Locust' THEN CAST(1 AS bit) -END = CAST(0 AS bit) OR CASE +END <> CAST(1 AS bit) OR CASE WHEN [f].[Name] = N'Locust' THEN CAST(1 AS bit) END IS NULL """); @@ -4497,7 +4497,7 @@ INNER JOIN ( FROM [Factions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [f] WHERE [f].[Name] = N'Swarm' ) AS [f0] ON [l].[Name] = [f0].[CommanderName] -WHERE [f0].[Eradicated] = CAST(0 AS bit) OR [f0].[Eradicated] IS NULL +WHERE [f0].[Eradicated] <> CAST(1 AS bit) OR [f0].[Eradicated] IS NULL """); } @@ -6446,7 +6446,7 @@ LEFT JOIN ( FROM [Factions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [f] WHERE [f].[Name] = N'Swarm' ) AS [f0] ON [l].[Name] = [f0].[CommanderName] -WHERE [f0].[Eradicated] = CAST(0 AS bit) OR [f0].[Eradicated] IS NULL +WHERE [f0].[Eradicated] <> CAST(1 AS bit) OR [f0].[Eradicated] IS NULL """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index aec1ce784fe..6e69f0b1ce3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -2874,7 +2874,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 +END <> 1 OR CASE WHEN "f"."Name" = 'Locust' THEN 1 END IS NULL """); @@ -5481,7 +5481,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" <> 1 OR "f0"."Eradicated" IS NULL """); } @@ -5549,7 +5549,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" <> 1 OR "f0"."Eradicated" IS NULL """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs index 7051721f131..f032b5b7bcd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindJoinQuerySqliteTest.cs @@ -57,4 +57,10 @@ public override async Task Take_in_collection_projection_with_FirstOrDefault_on_ SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Take_in_collection_projection_with_FirstOrDefault_on_top_level(async))).Message); + + public override async Task GroupJoin_on_true_equal_true(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.GroupJoin_on_true_equal_true(async))).Message); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs index e47b0c32c65..6a0ca3d271a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs @@ -222,6 +222,17 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) SELECT "e"."Id" FROM "Entities1" AS "e" WHERE "e"."BoolA" = "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", "e"."BoolA" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" """, // """ @@ -244,6 +255,17 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) SELECT "e"."Id" FROM "Entities1" AS "e" WHERE "e"."BoolA" <> "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") """, // """ @@ -266,6 +288,17 @@ 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) +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" = 1 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" """, // """ @@ -288,6 +321,61 @@ 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) +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" <> 1 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."NullableBoolA") +""", + // + """ +SELECT "e"."Id", "e"."BoolB" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolB" +""", + // + """ +SELECT "e"."Id", 1 = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolB") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolB") +""", + // + """ +SELECT "e"."Id", 0 = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 0 = "e"."NullableBoolB" """, // """ @@ -310,6 +398,17 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) SELECT "e"."Id" FROM "Entities1" AS "e" WHERE "e"."BoolA" <> "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") """, // """ @@ -332,6 +431,17 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) SELECT "e"."Id" FROM "Entities1" AS "e" WHERE "e"."BoolA" = "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", "e"."BoolA" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" """, // """ @@ -354,6 +464,17 @@ 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) +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" = 0 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" = 0 """, // """ @@ -379,91 +500,91 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."BoolB" AS "X" +SELECT "e"."Id", "e"."NullableBoolA" <> 0 AND "e"."NullableBoolA" IS NOT NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."NullableBoolA" <> 0 """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", NOT ("e"."BoolB") 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"."BoolB") """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."BoolB" AS "X" +SELECT "e"."Id", 1 <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."BoolB" +WHERE NOT ("e"."NullableBoolB") """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolB" 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"."BoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", 0 <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +WHERE 0 <> "e"."NullableBoolB" """, // """ -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"."BoolA" <> "e"."BoolB" 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"."BoolA" <> "e"."BoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -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"."BoolA") 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"."BoolA") """, // """ @@ -489,25 +610,47 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."BoolB" AS "X" +SELECT "e"."Id", "e"."BoolA" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."BoolA" """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL 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"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL +""", + // + """ +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" +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"."NullableBoolA" <> 1 OR "e"."NullableBoolA" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" <> 1 OR "e"."NullableBoolA" IS NULL """, // """ @@ -533,47 +676,58 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" = 1 OR "e"."NullableBoolA" IS NULL 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" = 1 OR "e"."NullableBoolA" IS NULL """, // """ -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"."BoolB") 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"."BoolB") """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."BoolB" AS "X" +SELECT "e"."Id", 1 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE 1 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolB" 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"."BoolB" +""", + // + """ +SELECT "e"."Id", 0 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 0 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ @@ -599,25 +753,47 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "e"."BoolA" 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"."BoolA" """, // """ -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"."BoolA" <> "e"."BoolB" 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"."BoolA" <> "e"."BoolB" +""", + // + """ +SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") """, // """ @@ -643,267 +819,795 @@ public override async Task Rewrite_compare_bool_with_bool(bool async) """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."BoolB" AS "X" +SELECT "e"."Id", "e"."NullableBoolA" <> 0 OR "e"."NullableBoolA" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."BoolB" +WHERE "e"."NullableBoolA" <> 0 OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL 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"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."BoolB" AS "X" +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" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +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"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" = 0 OR "e"."NullableBoolA" IS NULL 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"."NullableBoolA" = 0 OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", "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"."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", 1 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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 1 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" +SELECT "e"."Id", 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"."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", 0 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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 0 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."BoolB" AS "X" +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" +WHERE "e"."BoolA" <> "e"."BoolB" """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" +WHERE "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."BoolB" AS "X" +SELECT "e"."Id", NOT ("e"."BoolA") AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE NOT ("e"."BoolA") """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" = "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE "e"."BoolA" = "e"."BoolB" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" +WHERE "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -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"."BoolA" 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"."BoolA" """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL """, // """ -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" <> "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" 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 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" +SELECT "e"."Id", "e"."NullableBoolA" <> 1 OR "e"."NullableBoolA" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."BoolB" +WHERE "e"."NullableBoolA" <> 1 OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" <> "e"."NullableBoolB" +WHERE "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."BoolA" = "e"."BoolB" AS "X" +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" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."BoolB" +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"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."NullableBoolA" = 1 OR "e"."NullableBoolA" IS NULL AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."BoolA" = "e"."NullableBoolB" +WHERE "e"."NullableBoolA" = 1 OR "e"."NullableBoolA" IS NULL """, // """ -SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", NOT ("e"."BoolB") AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" <> "e"."BoolB" +WHERE NOT ("e"."BoolB") """, // """ -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", 1 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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 1 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL """, // """ -SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +SELECT "e"."Id", "e"."BoolB" AS "X" FROM "Entities1" AS "e" """, // """ SELECT "e"."Id" FROM "Entities1" AS "e" -WHERE "e"."NullableBoolA" = "e"."BoolB" +WHERE "e"."BoolB" """, // """ -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", 0 <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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 0 <> "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", "e"."BoolA" = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" +""", + // + """ +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", "e"."BoolA" <> "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL 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", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" OR "e"."NullableBoolA" IS NULL 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", ("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" +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"."NullableBoolA" <> 0 OR "e"."NullableBoolA" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" <> 0 OR "e"."NullableBoolA" IS NULL +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" OR "e"."NullableBoolA" IS NULL 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", ("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" +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"."NullableBoolA" = 0 OR "e"."NullableBoolA" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" = 0 OR "e"."NullableBoolA" IS NULL +""", + // + """ +SELECT "e"."Id", "e"."BoolB" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolB" +""", + // + """ +SELECT "e"."Id", 1 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 1 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolB") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolB") +""", + // + """ +SELECT "e"."Id", 0 = "e"."NullableBoolB" OR "e"."NullableBoolB" IS NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 0 = "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", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" = "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", "e"."BoolA" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" +""", + // + """ +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", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" <> "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" = "e"."BoolB" +""", + // + """ +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" +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"."NullableBoolA" = 1 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" <> "e"."BoolB" +""", + // + """ +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" +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"."NullableBoolA" <> 1 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."NullableBoolA") +""", + // + """ +SELECT "e"."Id", "e"."BoolB" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolB" +""", + // + """ +SELECT "e"."Id", 1 = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolB") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolB") +""", + // + """ +SELECT "e"."Id", 0 = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 0 = "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", "e"."BoolA" <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" <> "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolA") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolA") +""", + // + """ +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", "e"."BoolA" = "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" = "e"."NullableBoolB" +""", + // + """ +SELECT "e"."Id", "e"."BoolA" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolA" +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" <> "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" <> "e"."BoolB" +""", + // + """ +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" +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"."NullableBoolA" = 0 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" = 0 +""", + // + """ +SELECT "e"."Id", "e"."NullableBoolA" = "e"."BoolB" AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" = "e"."BoolB" +""", + // + """ +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" +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"."NullableBoolA" <> 0 AND "e"."NullableBoolA" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."NullableBoolA" <> 0 +""", + // + """ +SELECT "e"."Id", NOT ("e"."BoolB") AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."BoolB") +""", + // + """ +SELECT "e"."Id", 1 <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE NOT ("e"."NullableBoolB") +""", + // + """ +SELECT "e"."Id", "e"."BoolB" AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE "e"."BoolB" +""", + // + """ +SELECT "e"."Id", 0 <> "e"."NullableBoolB" AND "e"."NullableBoolB" IS NOT NULL AS "X" +FROM "Entities1" AS "e" +""", + // + """ +SELECT "e"."Id" +FROM "Entities1" AS "e" +WHERE 0 <> "e"."NullableBoolB" """); } From 4623a39d092611e34382d92c64448b92e9749133 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Wed, 29 Jan 2025 10:41:58 -0800 Subject: [PATCH 2/2] Make SnapshotModelProcessor idempotent. (#35543) Fixes #35146 --- .../Migrations/Internal/SnapshotModelProcessor.cs | 13 ++++++------- .../Migrations/Design/SnapshotModelProcessorTest.cs | 5 ++++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs b/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs index a47c283c472..30b89651e13 100644 --- a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs +++ b/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs @@ -52,7 +52,9 @@ public SnapshotModelProcessor( /// public virtual IModel? Process(IReadOnlyModel? model, bool resetVersion = false) { - if (model == null) + if (model == null + || model is not Model mutableModel + || mutableModel.IsReadOnly) { return null; } @@ -79,13 +81,10 @@ public SnapshotModelProcessor( } } - if (model is IMutableModel mutableModel) + mutableModel.RemoveAnnotation("ChangeDetector.SkipDetectChanges"); + if (resetVersion) { - mutableModel.RemoveAnnotation("ChangeDetector.SkipDetectChanges"); - if (resetVersion) - { - mutableModel.SetProductVersion(ProductInfo.GetVersion()); - } + mutableModel.SetProductVersion(ProductInfo.GetVersion()); } return _modelRuntimeInitializer.Initialize((IModel)model, designTime: true, validationLogger: null); diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs index 6cbc70fc2d8..c7070dcc763 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs @@ -43,7 +43,8 @@ public void Updates_provider_annotations_on_model() var reporter = new TestOperationReporter(); - new SnapshotModelProcessor(reporter, DummyModelRuntimeInitializer.Instance).Process(model); + var processor = new SnapshotModelProcessor(reporter, DummyModelRuntimeInitializer.Instance); + processor.Process(model); AssertAnnotations(model); AssertAnnotations(entityType); @@ -54,6 +55,8 @@ public void Updates_provider_annotations_on_model() AssertAnnotations(nav2); AssertAnnotations(index); + Assert.Same(model, processor.Process(model)); + Assert.Empty(reporter.Messages); }