diff --git a/src/EFCore.Relational/Query/Internal/NullSemanticsRewritingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/NullSemanticsRewritingExpressionVisitor.cs
index e35a76c166f..c1f8bf19ede 100644
--- a/src/EFCore.Relational/Query/Internal/NullSemanticsRewritingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/NullSemanticsRewritingExpressionVisitor.cs
@@ -14,10 +14,12 @@ public class NullSemanticsRewritingExpressionVisitor : ExpressionVisitor
 
         private bool _isNullable;
         private readonly List<ColumnExpression> _nonNullableColumns = new List<ColumnExpression>();
+        private IsNullOptimizingExpressionVisitor _isNullOptimizer;
 
         public NullSemanticsRewritingExpressionVisitor(ISqlExpressionFactory sqlExpressionFactory)
         {
             _sqlExpressionFactory = sqlExpressionFactory;
+            _isNullOptimizer = new IsNullOptimizingExpressionVisitor(sqlExpressionFactory);
         }
 
         protected override Expression VisitExtension(Expression extensionExpression)
@@ -242,11 +244,11 @@ private SqlBinaryExpression VisitSqlBinaryExpression(SqlBinaryExpression sqlBina
                     newRight = rightUnary.Operand;
                 }
 
-                // TODO: optimize this by looking at subcomponents, e.g. f(a, b) == null <=> a == null || b == null
-                var leftIsNull = _sqlExpressionFactory.IsNull(newLeft);
-                var rightIsNull = _sqlExpressionFactory.IsNull(newRight);
+                var leftIsNull = (SqlExpression)_isNullOptimizer.Visit(_sqlExpressionFactory.IsNull(newLeft));
+                var rightIsNull = (SqlExpression)_isNullOptimizer.Visit(_sqlExpressionFactory.IsNull(newRight));
 
                 // doing a full null semantics rewrite - removing all nulls from truth table
+                // this will NOT be correct once we introduce simplified null semantics
                 _isNullable = false;
 
                 if (sqlBinaryExpression.OperatorType == ExpressionType.Equal)
@@ -335,6 +337,46 @@ private SqlBinaryExpression VisitSqlBinaryExpression(SqlBinaryExpression sqlBina
             return sqlBinaryExpression.Update(newLeft, newRight);
         }
 
+        private class IsNullOptimizingExpressionVisitor : ExpressionVisitor
+        {
+            private readonly ISqlExpressionFactory _sqlExpressionFactory;
+
+            public IsNullOptimizingExpressionVisitor(ISqlExpressionFactory sqlExpressionFactory)
+            {
+                _sqlExpressionFactory = sqlExpressionFactory;
+            }
+
+            protected override Expression VisitExtension(Expression extensionExpression)
+            {
+                if (extensionExpression is SqlUnaryExpression sqlUnaryExpression
+                    && sqlUnaryExpression.OperatorType == ExpressionType.Equal)
+                {
+                    switch (sqlUnaryExpression.Operand)
+                    {
+                        case SqlUnaryExpression sqlUnaryOperand
+                        when sqlUnaryOperand.OperatorType == ExpressionType.Convert
+                            || sqlUnaryOperand.OperatorType == ExpressionType.Not
+                            || sqlUnaryOperand.OperatorType == ExpressionType.Negate:
+                            return (SqlExpression)Visit(_sqlExpressionFactory.IsNull(sqlUnaryOperand.Operand));
+
+                        case SqlBinaryExpression sqlBinaryOperand:
+                            var newLeft = (SqlExpression)Visit(_sqlExpressionFactory.IsNull(sqlBinaryOperand.Left));
+                            var newRight = (SqlExpression)Visit(_sqlExpressionFactory.IsNull(sqlBinaryOperand.Right));
+
+                            return sqlBinaryOperand.OperatorType == ExpressionType.Coalesce
+                                ? _sqlExpressionFactory.AndAlso(newLeft, newRight)
+                                : _sqlExpressionFactory.OrElse(newLeft, newRight);
+
+                        case ColumnExpression columnOperand
+                        when !columnOperand.IsNullable:
+                            return _sqlExpressionFactory.Constant(false, sqlUnaryExpression.TypeMapping);
+                    }
+                }
+
+                return base.VisitExtension(extensionExpression);
+            }
+        }
+
         private List<ColumnExpression> FindNonNullableColumns(SqlExpression sqlExpression)
         {
             var result = new List<ColumnExpression>();
diff --git a/src/EFCore.Relational/Query/Internal/SqlExpressionOptimizingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/SqlExpressionOptimizingExpressionVisitor.cs
index 4ff4fd7ee60..e5716379880 100644
--- a/src/EFCore.Relational/Query/Internal/SqlExpressionOptimizingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/SqlExpressionOptimizingExpressionVisitor.cs
@@ -3,6 +3,7 @@
 
 using System.Linq.Expressions;
 using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
+using Microsoft.EntityFrameworkCore.Storage;
 
 namespace Microsoft.EntityFrameworkCore.Query.Internal
 {
@@ -60,6 +61,16 @@ protected virtual Expression VisitSqlUnaryExpression(SqlUnaryExpression sqlUnary
                 return SqlExpressionFactory.Constant(innerConstantNull1.Value == null, sqlUnaryExpression.TypeMapping);
             }
 
+            // non_nullable_column IS NULL -> false
+            // non_nullable_column IS NOT NULL -> true
+            if ((sqlUnaryExpression.OperatorType == ExpressionType.Equal
+                    || sqlUnaryExpression.OperatorType == ExpressionType.NotEqual)
+                && sqlUnaryExpression.Operand is ColumnExpression innerColumn
+                && !innerColumn.IsNullable)
+            {
+                return SqlExpressionFactory.Constant(sqlUnaryExpression.OperatorType == ExpressionType.NotEqual, sqlUnaryExpression.TypeMapping);
+            }
+
             // NULL IS NOT NULL -> false
             // non_nullable_constant IS NOT NULL -> true
             if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual
@@ -135,9 +146,13 @@ private Expression VisitNot(SqlUnaryExpression sqlUnaryExpression)
                     var newLeft = (SqlExpression)Visit(SqlExpressionFactory.Not(innerBinary.Left));
                     var newRight = (SqlExpression)Visit(SqlExpressionFactory.Not(innerBinary.Right));
 
-                    return innerBinary.OperatorType == ExpressionType.AndAlso
-                        ? SqlExpressionFactory.OrElse(newLeft, newRight)
-                        : SqlExpressionFactory.AndAlso(newLeft, newRight);
+                    return CreateSqlBinaryEqualityExpression(
+                        innerBinary.OperatorType == ExpressionType.AndAlso
+                            ? ExpressionType.OrElse
+                            : ExpressionType.AndAlso,
+                        newLeft,
+                        newRight,
+                        innerBinary.TypeMapping);
                 }
 
                 // those optimizations are only valid in 2-value logic
@@ -168,36 +183,11 @@ private Expression VisitSqlBinaryExpression(SqlBinaryExpression sqlBinaryExpress
             if (sqlBinaryExpression.OperatorType == ExpressionType.AndAlso
                 || sqlBinaryExpression.OperatorType == ExpressionType.OrElse)
             {
-                // true && a -> a
-                // true || a -> true
-                // false && a -> false
-                // false || a -> a
-                if (newLeft is SqlConstantExpression newLeftConstant)
-                {
-                    return sqlBinaryExpression.OperatorType == ExpressionType.AndAlso
-                        ? (bool)newLeftConstant.Value
-                            ? newRight
-                            : newLeftConstant
-                        : (bool)newLeftConstant.Value
-                            ? newLeftConstant
-                            : newRight;
-                }
-                else if (newRight is SqlConstantExpression newRightConstant)
-                {
-                    // a && true -> a
-                    // a || true -> true
-                    // a && false -> false
-                    // a || false -> a
-                    return sqlBinaryExpression.OperatorType == ExpressionType.AndAlso
-                        ? (bool)newRightConstant.Value
-                            ? newLeft
-                            : newRightConstant
-                        : (bool)newRightConstant.Value
-                            ? newRightConstant
-                            : newLeft;
-                }
-
-                return sqlBinaryExpression.Update(newLeft, newRight);
+                return CreateSqlBinaryEqualityExpression(
+                    sqlBinaryExpression.OperatorType,
+                    newLeft,
+                    newRight,
+                    sqlBinaryExpression.TypeMapping);
             }
 
             // those optimizations are only valid in 2-value logic
@@ -227,5 +217,43 @@ private Expression VisitSqlBinaryExpression(SqlBinaryExpression sqlBinaryExpress
 
             return sqlBinaryExpression.Update(newLeft, newRight);
         }
+
+        private SqlExpression CreateSqlBinaryEqualityExpression(
+            ExpressionType operatorType,
+            SqlExpression newLeft,
+            SqlExpression newRight,
+            RelationalTypeMapping typeMapping)
+        {
+            // true && a -> a
+            // true || a -> true
+            // false && a -> false
+            // false || a -> a
+            if (newLeft is SqlConstantExpression newLeftConstant)
+            {
+                return operatorType == ExpressionType.AndAlso
+                    ? (bool)newLeftConstant.Value
+                        ? newRight
+                        : newLeftConstant
+                    : (bool)newLeftConstant.Value
+                        ? newLeftConstant
+                        : newRight;
+            }
+            else if (newRight is SqlConstantExpression newRightConstant)
+            {
+                // a && true -> a
+                // a || true -> true
+                // a && false -> false
+                // a || false -> a
+                return operatorType == ExpressionType.AndAlso
+                    ? (bool)newRightConstant.Value
+                        ? newLeft
+                        : newRightConstant
+                    : (bool)newRightConstant.Value
+                        ? newRightConstant
+                        : newLeft;
+            }
+
+            return SqlExpressionFactory.MakeBinary(operatorType, newLeft, newRight, typeMapping);
+        }
     }
 }
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ParameterNullabilityOptimizingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ParameterNullabilityOptimizingExpressionVisitor.cs
index 771aa6bfbd0..993dbe30b46 100644
--- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ParameterNullabilityOptimizingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ParameterNullabilityOptimizingExpressionVisitor.cs
@@ -30,16 +30,33 @@ protected override Expression VisitExtension(Expression extensionExpression)
                 {
                     var newSelectExpression = (SelectExpression)base.VisitExtension(extensionExpression);
 
-                    return newSelectExpression.Predicate is SqlConstantExpression newSelectPredicateConstant
+                    // if predicate is optimized to true, we can simply remove it
+                    var newPredicate = newSelectExpression.Predicate is SqlConstantExpression newSelectPredicateConstant
                         && !(selectExpression.Predicate is SqlConstantExpression)
+                        ? (bool)newSelectPredicateConstant.Value
+                            ? null
+                            : SqlExpressionFactory.Equal(
+                                newSelectPredicateConstant,
+                                SqlExpressionFactory.Constant(true, newSelectPredicateConstant.TypeMapping))
+                        : newSelectExpression.Predicate;
+
+                    var newHaving = newSelectExpression.Having is SqlConstantExpression newSelectHavingConstant
+                        && !(selectExpression.Having is SqlConstantExpression)
+                        ? (bool)newSelectHavingConstant.Value
+                            ? null
+                            : SqlExpressionFactory.Equal(
+                                newSelectHavingConstant,
+                                SqlExpressionFactory.Constant(true, newSelectHavingConstant.TypeMapping))
+                        : newSelectExpression.Having;
+
+                    return newPredicate != newSelectExpression.Predicate
+                        || newHaving != newSelectExpression.Having
                         ? newSelectExpression.Update(
                             newSelectExpression.Projection.ToList(),
                             newSelectExpression.Tables.ToList(),
-                            SqlExpressionFactory.Equal(
-                                newSelectPredicateConstant,
-                                SqlExpressionFactory.Constant(true, newSelectPredicateConstant.TypeMapping)),
+                            newPredicate,
                             newSelectExpression.GroupBy.ToList(),
-                            newSelectExpression.Having,
+                            newHaving,
                             newSelectExpression.Orderings.ToList(),
                             newSelectExpression.Limit,
                             newSelectExpression.Offset,
diff --git a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs
index 7ef6d75044a..f89d2a088a2 100644
--- a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs
+++ b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs
@@ -16,7 +16,7 @@ public class ColumnExpression : SqlExpression
         internal ColumnExpression(IProperty property, TableExpressionBase table, bool nullable)
             : this(
                 property.GetColumnName(), table, property.ClrType, property.GetRelationalTypeMapping(),
-                nullable || property.IsNullable || property.DeclaringEntityType.BaseType != null)
+                nullable || property.IsColumnNullable())
         {
         }
 
diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
index ec4fbc72b14..c137abca516 100644
--- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
@@ -8006,6 +8006,107 @@ public virtual Task Group_by_with_aggregate_max_on_entity_type(bool isAsync)
                     })));
         }
 
+        [ConditionalTheory(Skip = "issue #18492")]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task Group_by_on_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQueryScalar(
+                isAsync,
+                ss => ss.Set<Gear>().GroupBy(g => g.FullName.StartsWith(prm)).Select(g => g.Key));
+        }
+
+        [ConditionalTheory]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task Group_by_with_having_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().GroupBy(g => g.FullName).Where(g => g.Key.StartsWith(prm)).Select(g => g.Key),
+                ss => ss.Set<Gear>().GroupBy(g => g.FullName).Where(g => false).Select(g => g.Key));
+        }
+
+        [ConditionalTheory(Skip = "issue #18492")]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task Select_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQueryScalar(
+                isAsync,
+                ss => ss.Set<Gear>().Select(g => g.FullName.StartsWith(prm)),
+                ss => ss.Set<Gear>().Select(g => false));
+        }
+
+        [ConditionalTheory]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task Select_null_parameter_is_not_null(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQueryScalar(
+                isAsync,
+                ss => ss.Set<Gear>().Select(g => prm != null),
+                ss => ss.Set<Gear>().Select(g => false));
+        }
+
+        [ConditionalTheory]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task Where_null_parameter_is_not_null(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().Where(g => prm != null),
+                ss => ss.Set<Gear>().Where(g => false));
+        }
+
+        [ConditionalTheory(Skip = "issue #18492")]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual Task OrderBy_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            var prm = (string)null;
+
+            return AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().OrderBy(g => g.FullName.StartsWith(prm)).ThenBy(g => g.Nickname),
+                ss => ss.Set<Gear>().OrderBy(g => false).ThenBy(g => g.Nickname),
+                assertOrder: true);
+        }
+
+        [ConditionalTheory]
+        [MemberData(nameof(IsAsyncData))]
+        public virtual async Task Where_with_enum_flags_parameter(bool isAsync)
+        {
+            MilitaryRank? rank = MilitaryRank.Private;
+
+            await AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().Where(g => (g.Rank & rank) == rank));
+
+            rank = null;
+
+            await AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().Where(g => (g.Rank & rank) == rank));
+
+            rank = MilitaryRank.Corporal;
+
+            await AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().Where(g => (g.Rank | rank) != rank));
+
+            rank = null;
+
+            await AssertQuery(
+                isAsync,
+                ss => ss.Set<Gear>().Where(g => (g.Rank | rank) != rank));
+        }
+
         protected async Task AssertTranslationFailed(Func<Task> testCode)
         {
             Assert.Contains(
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
index aac491cb831..500d5ead532 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
@@ -564,7 +564,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -572,7 +572,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -592,7 +592,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND (1 & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -600,7 +600,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR (1 & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -626,7 +626,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -634,7 +634,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -654,7 +654,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND (1 & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -662,7 +662,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR (1 & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -688,7 +688,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId])) AND ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -696,7 +696,7 @@ WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
-    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ([g].[Rank] & (
+    ORDER BY [g0].[Nickname], [g0].[SquadId]) IS NOT NULL)) OR ((
     SELECT TOP(1) [g0].[Rank]
     FROM [Gears] AS [g0]
     WHERE [g0].[Discriminator] IN (N'Gear', N'Officer')
@@ -716,7 +716,7 @@ public override async Task Where_enum_has_flag_with_non_nullable_parameter(bool
 
 SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
 FROM [Gears] AS [g]
-WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND ((([g].[Rank] & @__parameter_0) = @__parameter_0) AND [g].[Rank] & @__parameter_0 IS NOT NULL)");
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND (([g].[Rank] & @__parameter_0) = @__parameter_0)");
         }
 
         public override async Task Where_has_flag_with_nullable_parameter(bool isAsync)
@@ -728,7 +728,7 @@ public override async Task Where_has_flag_with_nullable_parameter(bool isAsync)
 
 SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
 FROM [Gears] AS [g]
-WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND ((([g].[Rank] & @__parameter_0) = @__parameter_0) AND [g].[Rank] & @__parameter_0 IS NOT NULL)");
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND (([g].[Rank] & @__parameter_0) = @__parameter_0)");
         }
 
         public override async Task Select_enum_has_flag(bool isAsync)
@@ -1122,7 +1122,7 @@ public override async Task Select_null_propagation_negative6(bool isAsync)
             AssertSql(
                 @"SELECT CASE
     WHEN [g].[LeaderNickname] IS NOT NULL THEN CASE
-        WHEN ((CAST(LEN([g].[LeaderNickname]) AS int) <> CAST(LEN([g].[LeaderNickname]) AS int)) OR (CAST(LEN([g].[LeaderNickname]) AS int) IS NULL OR CAST(LEN([g].[LeaderNickname]) AS int) IS NULL)) AND (CAST(LEN([g].[LeaderNickname]) AS int) IS NOT NULL OR CAST(LEN([g].[LeaderNickname]) AS int) IS NOT NULL) THEN CAST(1 AS bit)
+        WHEN ((CAST(LEN([g].[LeaderNickname]) AS int) <> CAST(LEN([g].[LeaderNickname]) AS int)) OR (LEN([g].[LeaderNickname]) IS NULL OR LEN([g].[LeaderNickname]) IS NULL)) AND (LEN([g].[LeaderNickname]) IS NOT NULL OR LEN([g].[LeaderNickname]) IS NOT NULL) THEN CAST(1 AS bit)
         ELSE CAST(0 AS bit)
     END
     ELSE NULL
@@ -6694,8 +6694,7 @@ FROM [Weapons] AS [w]
     ORDER BY [w].[Id]) IS NOT NULL)");
         }
 
-        public override async Task Query_with_complex_let_containing_ordering_and_filter_projecting_firstOrDefault_element_of_let(
-            bool isAsync)
+        public override async Task Query_with_complex_let_containing_ordering_and_filter_projecting_firstOrDefault_element_of_let(bool isAsync)
         {
             await base.Query_with_complex_let_containing_ordering_and_filter_projecting_firstOrDefault_element_of_let(isAsync);
 
@@ -6709,8 +6708,7 @@ FROM [Gears] AS [g]
 WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND ([g].[Nickname] <> N'Dom')");
         }
 
-        public override async Task
-            Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation(bool isAsync)
+        public override async Task Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation(bool isAsync)
         {
             await base.Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation(isAsync);
 
@@ -6721,8 +6719,7 @@ public override async Task
         public override async Task
             Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation_complex(bool isAsync)
         {
-            await base.Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation_complex(
-                isAsync);
+            await base.Null_semantics_is_correctly_applied_for_function_comparisons_that_take_arguments_from_optional_navigation_complex(isAsync);
 
             AssertSql(
                 @"SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[Note]
@@ -7416,6 +7413,93 @@ WHERE [g].[Discriminator] IN (N'Gear', N'Officer')
 GROUP BY [c].[Name]");
         }
 
+        public override async Task Group_by_on_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            await base.Group_by_on_StartsWith_with_null_parameter_as_argument(isAsync);
+
+            AssertSql(
+                @"");
+        }
+
+        public override async Task Group_by_with_having_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            await base.Group_by_with_having_StartsWith_with_null_parameter_as_argument(isAsync);
+
+            AssertSql(
+                @"SELECT [g].[FullName]
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer')
+GROUP BY [g].[FullName]
+HAVING CAST(0 AS bit) = CAST(1 AS bit)");
+        }
+
+        public override async Task Select_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            await base.Select_StartsWith_with_null_parameter_as_argument(isAsync);
+
+            AssertSql(
+                @"");
+        }
+
+        public override async Task Select_null_parameter_is_not_null(bool isAsync)
+        {
+            await base.Select_null_parameter_is_not_null(isAsync);
+
+            AssertSql(
+                @"@__p_0='False'
+
+SELECT @__p_0
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer')");
+        }
+
+        public override async Task Where_null_parameter_is_not_null(bool isAsync)
+        {
+            await base.Where_null_parameter_is_not_null(isAsync);
+
+            AssertSql(
+                @"@__p_0='False'
+
+SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND (@__p_0 = CAST(1 AS bit))");
+        }
+
+        public override async Task OrderBy_StartsWith_with_null_parameter_as_argument(bool isAsync)
+        {
+            await base.OrderBy_StartsWith_with_null_parameter_as_argument(isAsync);
+
+            AssertSql(
+                @"");
+        }
+
+        public override async Task Where_with_enum_flags_parameter(bool isAsync)
+        {
+            await base.Where_with_enum_flags_parameter(isAsync);
+
+            AssertSql(
+                @"@__rank_0='0' (Nullable = true)
+
+SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND (([g].[Rank] & @__rank_0) = @__rank_0)",
+                //
+                @"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer')",
+                //
+                @"@__rank_0='1' (Nullable = true)
+
+SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
+FROM [Gears] AS [g]
+WHERE [g].[Discriminator] IN (N'Gear', N'Officer') AND (([g].[Rank] | @__rank_0) <> @__rank_0)",
+                //
+                @"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
+FROM [Gears] AS [g]
+WHERE CAST(0 AS bit) = CAST(1 AS bit)");
+
+        }
+
         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 acbc08a838a..e2e1f384df9 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs
@@ -834,7 +834,7 @@ public override void Where_equal_with_coalesce()
             AssertSql(
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE ((COALESCE([e].[NullableStringA], [e].[NullableStringB]) = [e].[NullableStringC]) AND (COALESCE([e].[NullableStringA], [e].[NullableStringB]) IS NOT NULL AND [e].[NullableStringC] IS NOT NULL)) OR (COALESCE([e].[NullableStringA], [e].[NullableStringB]) IS NULL AND [e].[NullableStringC] IS NULL)");
+WHERE ((COALESCE([e].[NullableStringA], [e].[NullableStringB]) = [e].[NullableStringC]) AND (([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) AND [e].[NullableStringC] IS NOT NULL)) OR (([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) AND [e].[NullableStringC] IS NULL)");
         }
 
         public override void Where_not_equal_with_coalesce()
@@ -844,7 +844,7 @@ public override void Where_not_equal_with_coalesce()
             AssertSql(
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE ((COALESCE([e].[NullableStringA], [e].[NullableStringB]) <> [e].[NullableStringC]) OR (COALESCE([e].[NullableStringA], [e].[NullableStringB]) IS NULL OR [e].[NullableStringC] IS NULL)) AND (COALESCE([e].[NullableStringA], [e].[NullableStringB]) IS NOT NULL OR [e].[NullableStringC] IS NOT NULL)");
+WHERE ((COALESCE([e].[NullableStringA], [e].[NullableStringB]) <> [e].[NullableStringC]) OR (([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL) OR [e].[NullableStringC] IS NULL)) AND (([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL) OR [e].[NullableStringC] IS NOT NULL)");
         }
 
         public override void Where_equal_with_coalesce_both_sides()
@@ -854,7 +854,7 @@ public override void Where_equal_with_coalesce_both_sides()
             AssertSql(
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE (COALESCE([e].[NullableStringA], [e].[NullableStringB]) = COALESCE([e].[StringA], [e].[StringB])) AND COALESCE([e].[NullableStringA], [e].[NullableStringB]) IS NOT NULL");
+WHERE (COALESCE([e].[NullableStringA], [e].[NullableStringB]) = COALESCE([e].[StringA], [e].[StringB])) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL)");
         }
 
         public override void Where_not_equal_with_coalesce_both_sides()
@@ -864,7 +864,7 @@ public override void Where_not_equal_with_coalesce_both_sides()
             AssertSql(
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE ((COALESCE([e].[NullableIntA], [e].[NullableIntB]) <> COALESCE([e].[NullableIntC], [e].[NullableIntB])) OR (COALESCE([e].[NullableIntA], [e].[NullableIntB]) IS NULL OR COALESCE([e].[NullableIntC], [e].[NullableIntB]) IS NULL)) AND (COALESCE([e].[NullableIntA], [e].[NullableIntB]) IS NOT NULL OR COALESCE([e].[NullableIntC], [e].[NullableIntB]) IS NOT NULL)");
+WHERE ((COALESCE([e].[NullableIntA], [e].[NullableIntB]) <> COALESCE([e].[NullableIntC], [e].[NullableIntB])) OR (([e].[NullableIntA] IS NULL AND [e].[NullableIntB] IS NULL) OR ([e].[NullableIntC] IS NULL AND [e].[NullableIntB] IS NULL))) AND (([e].[NullableIntA] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL) OR ([e].[NullableIntC] IS NOT NULL OR [e].[NullableIntB] IS NOT NULL))");
         }
 
         public override void Where_equal_with_conditional()
@@ -1317,7 +1317,7 @@ FROM [Entities1] AS [e]
                 //
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE (([e].[NullableBoolA] = COALESCE([e].[NullableBoolB], [e].[NullableBoolC])) AND ([e].[NullableBoolA] IS NOT NULL AND COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) IS NOT NULL)) OR ([e].[NullableBoolA] IS NULL AND COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) IS NULL)",
+WHERE (([e].[NullableBoolA] = COALESCE([e].[NullableBoolB], [e].[NullableBoolC])) AND ([e].[NullableBoolA] IS NOT NULL AND ([e].[NullableBoolB] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL))) OR ([e].[NullableBoolA] IS NULL AND ([e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL))",
                 //
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
@@ -1325,7 +1325,7 @@ FROM [Entities1] AS [e]
                 //
                 @"SELECT [e].[Id]
 FROM [Entities1] AS [e]
-WHERE ((COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) <> [e].[NullableBoolA]) OR (COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) IS NULL OR [e].[NullableBoolA] IS NULL)) AND (COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) IS NOT NULL OR [e].[NullableBoolA] IS NOT NULL)");
+WHERE ((COALESCE([e].[NullableBoolB], [e].[NullableBoolC]) <> [e].[NullableBoolA]) OR (([e].[NullableBoolB] IS NULL AND [e].[NullableBoolC] IS NULL) OR [e].[NullableBoolA] IS NULL)) AND (([e].[NullableBoolB] IS NOT NULL OR [e].[NullableBoolC] IS NOT NULL) OR [e].[NullableBoolA] IS NOT NULL)");
         }
 
         public override void Null_semantics_conditional()
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.ResultOperators.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.ResultOperators.cs
index f78d1e1d294..25fe8f84cc8 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.ResultOperators.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.ResultOperators.cs
@@ -820,7 +820,7 @@ public override async Task Contains_with_local_list_closure_all_null(bool isAsyn
             AssertSql(
                 @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
 FROM [Customers] AS [c]
-WHERE [c].[CustomerID] IS NULL");
+WHERE CAST(0 AS bit) = CAST(1 AS bit)");
         }
 
         public override async Task Contains_with_local_list_inline(bool isAsync)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
index 4017e3d88c6..7c092752f8d 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
@@ -129,13 +129,13 @@ public override async Task Where_method_call_nullable_type_closure_via_query_cac
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL",
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL",
                 //
                 @"@__p_0='5' (Nullable = true)
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL");
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL");
         }
 
         public override async Task Where_method_call_nullable_type_reverse_closure_via_query_cache(bool isAsync)
@@ -327,17 +327,17 @@ public override async Task Where_simple_closure_via_query_cache_nullable_type(bo
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL",
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL",
                 //
                 @"@__p_0='5' (Nullable = true)
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL",
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL",
                 //
                 @"SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE CAST([e].[ReportsTo] AS bigint) IS NULL");
+WHERE [e].[ReportsTo] IS NULL");
         }
 
         public override async Task Where_simple_closure_via_query_cache_nullable_type_reverse(bool isAsync)
@@ -347,19 +347,19 @@ public override async Task Where_simple_closure_via_query_cache_nullable_type_re
             AssertSql(
                 @"SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE CAST([e].[ReportsTo] AS bigint) IS NULL",
+WHERE [e].[ReportsTo] IS NULL",
                 //
                 @"@__p_0='5' (Nullable = true)
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL",
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL",
                 //
                 @"@__p_0='2' (Nullable = true)
 
 SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
 FROM [Employees] AS [e]
-WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND CAST([e].[ReportsTo] AS bigint) IS NOT NULL");
+WHERE (CAST([e].[ReportsTo] AS bigint) = @__p_0) AND [e].[ReportsTo] IS NOT NULL");
         }
 
         public override void Where_subquery_closure_via_query_cache()
@@ -647,7 +647,7 @@ public override async Task Where_string_length(bool isAsync)
             AssertSql(
                 @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
 FROM [Customers] AS [c]
-WHERE (CAST(LEN([c].[City]) AS int) = 6) AND CAST(LEN([c].[City]) AS int) IS NOT NULL");
+WHERE (CAST(LEN([c].[City]) AS int) = 6) AND LEN([c].[City]) IS NOT NULL");
         }
 
         public override async Task Where_string_indexof(bool isAsync)
@@ -1292,7 +1292,7 @@ public override async Task Where_concat_string_int_comparison1(bool isAsync)
 
 SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE ((([c].[CustomerID] + CAST(@__i_0 AS nchar(5))) = [c].[CompanyName]) AND ([c].[CustomerID] + CAST(@__i_0 AS nchar(5)) IS NOT NULL AND [c].[CompanyName] IS NOT NULL)) OR ([c].[CustomerID] + CAST(@__i_0 AS nchar(5)) IS NULL AND [c].[CompanyName] IS NULL)");
+WHERE (([c].[CustomerID] + CAST(@__i_0 AS nchar(5))) = [c].[CompanyName]) AND [c].[CompanyName] IS NOT NULL");
         }
 
         public override async Task Where_concat_string_int_comparison2(bool isAsync)
@@ -1304,7 +1304,7 @@ public override async Task Where_concat_string_int_comparison2(bool isAsync)
 
 SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE (((CAST(@__i_0 AS nchar(5)) + [c].[CustomerID]) = [c].[CompanyName]) AND (CAST(@__i_0 AS nchar(5)) + [c].[CustomerID] IS NOT NULL AND [c].[CompanyName] IS NOT NULL)) OR (CAST(@__i_0 AS nchar(5)) + [c].[CustomerID] IS NULL AND [c].[CompanyName] IS NULL)");
+WHERE ((CAST(@__i_0 AS nchar(5)) + [c].[CustomerID]) = [c].[CompanyName]) AND [c].[CompanyName] IS NOT NULL");
         }
 
         public override async Task Where_concat_string_int_comparison3(bool isAsync)
@@ -1317,7 +1317,7 @@ public override async Task Where_concat_string_int_comparison3(bool isAsync)
 
 SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE (((((CAST(@__p_0 AS nchar(5)) + [c].[CustomerID]) + CAST(@__j_1 AS nchar(5))) + CAST(42 AS nchar(5))) = [c].[CompanyName]) AND (((CAST(@__p_0 AS nchar(5)) + [c].[CustomerID]) + CAST(@__j_1 AS nchar(5))) + CAST(42 AS nchar(5)) IS NOT NULL AND [c].[CompanyName] IS NOT NULL)) OR (((CAST(@__p_0 AS nchar(5)) + [c].[CustomerID]) + CAST(@__j_1 AS nchar(5))) + CAST(42 AS nchar(5)) IS NULL AND [c].[CompanyName] IS NULL)");
+WHERE ((((CAST(@__p_0 AS nchar(5)) + [c].[CustomerID]) + CAST(@__j_1 AS nchar(5))) + CAST(42 AS nchar(5))) = [c].[CompanyName]) AND [c].[CompanyName] IS NOT NULL");
         }
 
         public override async Task Where_concat_string_int_comparison4(bool isAsync)
@@ -1327,7 +1327,7 @@ public override async Task Where_concat_string_int_comparison4(bool isAsync)
             AssertSql(
                 @"SELECT [o].[CustomerID]
 FROM [Orders] AS [o]
-WHERE (((CAST([o].[OrderID] AS nchar(5)) + [o].[CustomerID]) = [o].[CustomerID]) AND (CAST([o].[OrderID] AS nchar(5)) + [o].[CustomerID] IS NOT NULL AND [o].[CustomerID] IS NOT NULL)) OR (CAST([o].[OrderID] AS nchar(5)) + [o].[CustomerID] IS NULL AND [o].[CustomerID] IS NULL)");
+WHERE (((CAST([o].[OrderID] AS nchar(5)) + [o].[CustomerID]) = [o].[CustomerID]) AND ([o].[CustomerID] IS NOT NULL AND [o].[CustomerID] IS NOT NULL)) OR ([o].[CustomerID] IS NULL AND [o].[CustomerID] IS NULL)");
         }
 
         public override async Task Where_concat_string_string_comparison(bool isAsync)
@@ -1339,7 +1339,7 @@ public override async Task Where_concat_string_string_comparison(bool isAsync)
 
 SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE (((@__i_0 + [c].[CustomerID]) = [c].[CompanyName]) AND (@__i_0 + [c].[CustomerID] IS NOT NULL AND [c].[CompanyName] IS NOT NULL)) OR (@__i_0 + [c].[CustomerID] IS NULL AND [c].[CompanyName] IS NULL)");
+WHERE ((@__i_0 + [c].[CustomerID]) = [c].[CompanyName]) AND [c].[CompanyName] IS NOT NULL");
         }
 
         public override async Task Where_string_concat_method_comparison(bool isAsync)
@@ -1351,7 +1351,7 @@ public override async Task Where_string_concat_method_comparison(bool isAsync)
 
 SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE (((@__i_0 + [c].[CustomerID]) = [c].[CompanyName]) AND (@__i_0 + [c].[CustomerID] IS NOT NULL AND [c].[CompanyName] IS NOT NULL)) OR (@__i_0 + [c].[CustomerID] IS NULL AND [c].[CompanyName] IS NULL)");
+WHERE ((@__i_0 + [c].[CustomerID]) = [c].[CompanyName]) AND [c].[CompanyName] IS NOT NULL");
         }
 
         public override async Task Where_ternary_boolean_condition_true(bool isAsync)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs
index 4035d17a34d..84c8615ee35 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs
@@ -1522,7 +1522,7 @@ public override async Task All_top_level_column(bool isAsync)
     WHEN NOT EXISTS (
         SELECT 1
         FROM [Customers] AS [c]
-        WHERE (([c].[ContactName] <> N'') OR [c].[ContactName] IS NULL) AND ((([c].[ContactName] IS NULL AND ([c].[ContactName] IS NOT NULL AND (CAST(0 AS bit) = CAST(1 AS bit)))) OR ([c].[ContactName] IS NULL AND (CAST(1 AS bit) = CAST(1 AS bit)))) OR (([c].[ContactName] IS NULL AND (CAST(0 AS bit) = CAST(1 AS bit))) OR (LEFT([c].[ContactName], LEN([c].[ContactName])) <> [c].[ContactName])))) THEN CAST(1 AS bit)
+        WHERE (([c].[ContactName] <> N'') OR [c].[ContactName] IS NULL) AND ([c].[ContactName] IS NULL OR (LEFT([c].[ContactName], LEN([c].[ContactName])) <> [c].[ContactName]))) THEN CAST(1 AS bit)
     ELSE CAST(0 AS bit)
 END");
         }
@@ -2078,7 +2078,7 @@ FROM [Customers] AS [c]
             ORDER BY [c].[CustomerID]
             OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
         ) AS [t]
-        WHERE ([t].[CustomerID] IS NULL AND (CAST(0 AS bit) = CAST(1 AS bit))) OR NOT ([t].[CustomerID] LIKE N'B%')) THEN CAST(1 AS bit)
+        WHERE NOT ([t].[CustomerID] LIKE N'B%')) THEN CAST(1 AS bit)
     ELSE CAST(0 AS bit)
 END");
         }
@@ -2099,7 +2099,7 @@ SELECT TOP(@__p_0) [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName
             FROM [Customers] AS [c]
             ORDER BY [c].[CustomerID]
         ) AS [t]
-        WHERE ([t].[CustomerID] IS NULL AND (CAST(0 AS bit) = CAST(1 AS bit))) OR NOT ([t].[CustomerID] LIKE N'A%')) THEN CAST(1 AS bit)
+        WHERE NOT ([t].[CustomerID] LIKE N'A%')) THEN CAST(1 AS bit)
     ELSE CAST(0 AS bit)
 END");
         }
@@ -2641,7 +2641,7 @@ public override async Task Filter_coalesce_operator(bool isAsync)
             AssertSql(
                 @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
 FROM [Customers] AS [c]
-WHERE (COALESCE([c].[CompanyName], [c].[ContactName]) = N'The Big Cheese') AND COALESCE([c].[CompanyName], [c].[ContactName]) IS NOT NULL");
+WHERE (COALESCE([c].[CompanyName], [c].[ContactName]) = N'The Big Cheese') AND ([c].[CompanyName] IS NOT NULL OR [c].[ContactName] IS NOT NULL)");
         }
 
         [SqlServerCondition(SqlServerCondition.SupportsOffset)]
@@ -3693,7 +3693,7 @@ public override async Task Anonymous_complex_distinct_where(bool isAsync)
             AssertSql(
                 @"SELECT DISTINCT [c].[CustomerID] + [c].[City] AS [A]
 FROM [Customers] AS [c]
-WHERE (([c].[CustomerID] + [c].[City]) = N'ALFKIBerlin') AND [c].[CustomerID] + [c].[City] IS NOT NULL");
+WHERE (([c].[CustomerID] + [c].[City]) = N'ALFKIBerlin') AND [c].[City] IS NOT NULL");
         }
 
         public override async Task Anonymous_complex_distinct_orderby(bool isAsync)
@@ -3797,7 +3797,7 @@ public override async Task DTO_complex_distinct_where(bool isAsync)
             AssertSql(
                 @"SELECT DISTINCT [c].[CustomerID] + [c].[City] AS [Property]
 FROM [Customers] AS [c]
-WHERE (([c].[CustomerID] + [c].[City]) = N'ALFKIBerlin') AND [c].[CustomerID] + [c].[City] IS NOT NULL");
+WHERE (([c].[CustomerID] + [c].[City]) = N'ALFKIBerlin') AND [c].[City] IS NOT NULL");
         }
 
         public override async Task DTO_complex_distinct_orderby(bool isAsync)
@@ -4277,7 +4277,7 @@ public override async Task Comparing_entity_to_null_using_Equals(bool isAsync)
             AssertSql(
                 @"SELECT [c].[CustomerID]
 FROM [Customers] AS [c]
-WHERE ([c].[CustomerID] LIKE N'A%') AND ([c].[CustomerID] IS NOT NULL OR (CAST(1 AS bit) = CAST(1 AS bit)))
+WHERE [c].[CustomerID] LIKE N'A%'
 ORDER BY [c].[CustomerID]");
         }
 
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SpatialQuerySqlServerGeographyTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SpatialQuerySqlServerGeographyTest.cs
index 83222dd103b..a252b5cd101 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/SpatialQuerySqlServerGeographyTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/SpatialQuerySqlServerGeographyTest.cs
@@ -327,7 +327,7 @@ public override async Task GetInteriorRingN(bool isAsync)
 
             AssertSql(
                 @"SELECT [p].[Id], CASE
-    WHEN [p].[Polygon] IS NULL OR ((([p].[Polygon].NumRings() - 1) = 0) AND [p].[Polygon].NumRings() - 1 IS NOT NULL) THEN NULL
+    WHEN [p].[Polygon] IS NULL OR ((([p].[Polygon].NumRings() - 1) = 0) AND [p].[Polygon].NumRings() IS NOT NULL) THEN NULL
     ELSE [p].[Polygon].RingN(0 + 2)
 END AS [InteriorRing0]
 FROM [PolygonEntity] AS [p]");
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs
index 64abd1c92c6..a90444f93db 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs
@@ -494,7 +494,7 @@ public override async Task Where_datetime_year_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%Y', ""o"".""OrderDate"") AS INTEGER) = 1998) AND CAST(strftime('%Y', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%Y', ""o"".""OrderDate"") AS INTEGER) = 1998) AND strftime('%Y', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_month_component(bool isAsync)
@@ -504,7 +504,7 @@ public override async Task Where_datetime_month_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%m', ""o"".""OrderDate"") AS INTEGER) = 4) AND CAST(strftime('%m', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%m', ""o"".""OrderDate"") AS INTEGER) = 4) AND strftime('%m', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_dayOfYear_component(bool isAsync)
@@ -514,7 +514,7 @@ public override async Task Where_datetime_dayOfYear_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%j', ""o"".""OrderDate"") AS INTEGER) = 68) AND CAST(strftime('%j', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%j', ""o"".""OrderDate"") AS INTEGER) = 68) AND strftime('%j', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_day_component(bool isAsync)
@@ -524,7 +524,7 @@ public override async Task Where_datetime_day_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%d', ""o"".""OrderDate"") AS INTEGER) = 4) AND CAST(strftime('%d', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%d', ""o"".""OrderDate"") AS INTEGER) = 4) AND strftime('%d', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_hour_component(bool isAsync)
@@ -534,7 +534,7 @@ public override async Task Where_datetime_hour_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%H', ""o"".""OrderDate"") AS INTEGER) = 14) AND CAST(strftime('%H', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%H', ""o"".""OrderDate"") AS INTEGER) = 14) AND strftime('%H', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_minute_component(bool isAsync)
@@ -544,7 +544,7 @@ public override async Task Where_datetime_minute_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%M', ""o"".""OrderDate"") AS INTEGER) = 23) AND CAST(strftime('%M', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%M', ""o"".""OrderDate"") AS INTEGER) = 23) AND strftime('%M', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         public override async Task Where_datetime_second_component(bool isAsync)
@@ -554,7 +554,7 @@ public override async Task Where_datetime_second_component(bool isAsync)
             AssertSql(
                 @"SELECT ""o"".""OrderID"", ""o"".""CustomerID"", ""o"".""EmployeeID"", ""o"".""OrderDate""
 FROM ""Orders"" AS ""o""
-WHERE (CAST(strftime('%S', ""o"".""OrderDate"") AS INTEGER) = 44) AND CAST(strftime('%S', ""o"".""OrderDate"") AS INTEGER) IS NOT NULL");
+WHERE (CAST(strftime('%S', ""o"".""OrderDate"") AS INTEGER) = 44) AND strftime('%S', ""o"".""OrderDate"") IS NOT NULL");
         }
 
         [ConditionalTheory(Skip = "Issue#15586")]
@@ -715,7 +715,7 @@ public override async Task Where_string_indexof(bool isAsync)
             AssertSql(
                 @"SELECT ""c"".""CustomerID"", ""c"".""Address"", ""c"".""City"", ""c"".""CompanyName"", ""c"".""ContactName"", ""c"".""ContactTitle"", ""c"".""Country"", ""c"".""Fax"", ""c"".""Phone"", ""c"".""PostalCode"", ""c"".""Region""
 FROM ""Customers"" AS ""c""
-WHERE ((instr(""c"".""City"", 'Sea') - 1) <> -1) OR instr(""c"".""City"", 'Sea') - 1 IS NULL");
+WHERE ((instr(""c"".""City"", 'Sea') - 1) <> -1) OR instr(""c"".""City"", 'Sea') IS NULL");
         }
 
         public override async Task Indexof_with_emptystring(bool isAsync)