diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 54be16fe79f..d24a5470219 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -751,6 +751,7 @@ protected virtual SqlExpression VisitScalarSubquery( return scalarSubqueryExpression.Update(Visit(scalarSubqueryExpression.Subquery)); } + /// /// Visits a and computes its nullability. /// @@ -758,12 +759,44 @@ protected virtual SqlExpression VisitScalarSubquery( /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlBinary( [NotNull] SqlBinaryExpression sqlBinaryExpression, bool allowOptimizedExpansion, out bool nullable) { Check.NotNull(sqlBinaryExpression, nameof(sqlBinaryExpression)); + // we need to do this before we visit left/right + // otherwise detecting CompareTo block becomes hard due to null semantics expansion + // also we need to apply null semantics on the potential result + var sqlConstantExpression = sqlBinaryExpression.Left as SqlConstantExpression ?? sqlBinaryExpression.Right as SqlConstantExpression; + var caseExpression = sqlBinaryExpression.Left as CaseExpression ?? sqlBinaryExpression.Right as CaseExpression; + if (sqlConstantExpression != null + && sqlConstantExpression.Value != null + && IsCompareTo(caseExpression) + && sqlConstantExpression.Value is int intValue + && (intValue == 0 || intValue == 1 || intValue == -1) + && (sqlBinaryExpression.OperatorType == ExpressionType.NotEqual + || sqlBinaryExpression.OperatorType == ExpressionType.GreaterThan + || sqlBinaryExpression.OperatorType == ExpressionType.GreaterThanOrEqual + || sqlBinaryExpression.OperatorType == ExpressionType.LessThan + || sqlBinaryExpression.OperatorType == ExpressionType.LessThanOrEqual)) + { + var compareToOptimized = OptimizeCompareTo( + sqlBinaryExpression, + intValue, + caseExpression); + + if (compareToOptimized is SqlConstantExpression) + { + nullable = true; + + return compareToOptimized; + } + else + { + sqlBinaryExpression = (SqlBinaryExpression)compareToOptimized; + } + } + var optimize = allowOptimizedExpansion; allowOptimizedExpansion = allowOptimizedExpansion @@ -862,7 +895,6 @@ protected virtual SqlExpression VisitSqlBinary( } nullable = leftNullable || rightNullable; - var result = sqlBinaryExpression.Update(left, right); return result is SqlBinaryExpression sqlBinaryResult @@ -876,6 +908,121 @@ SqlExpression AddNullConcatenationProtection(SqlExpression argument, RelationalT ? (SqlExpression)_sqlExpressionFactory.Constant(string.Empty, typeMapping) : _sqlExpressionFactory.Coalesce(argument, _sqlExpressionFactory.Constant(string.Empty, typeMapping)); } + + private bool IsCompareTo(CaseExpression caseExpression) + { + if (caseExpression != null + && caseExpression.Operand == null + && caseExpression.WhenClauses.Count == 3 + && caseExpression.WhenClauses.All(c => c.Test is SqlBinaryExpression + && c.Result is SqlConstantExpression constant + && constant.Value is int)) + { + var whenClauses = caseExpression.WhenClauses.Select(c => new + { + test = (SqlBinaryExpression)c.Test, + resultValue = (int)((SqlConstantExpression)c.Result).Value + }).ToList(); + + if (whenClauses[0].test.Left.Equals(whenClauses[1].test.Left) + && whenClauses[1].test.Left.Equals(whenClauses[2].test.Left) + && whenClauses[0].test.Right.Equals(whenClauses[1].test.Right) + && whenClauses[1].test.Right.Equals(whenClauses[2].test.Right) + && whenClauses[0].test.OperatorType == ExpressionType.Equal + && whenClauses[1].test.OperatorType == ExpressionType.GreaterThan + && whenClauses[2].test.OperatorType == ExpressionType.LessThan + && whenClauses[0].resultValue == 0 + && whenClauses[1].resultValue == 1 + && whenClauses[2].resultValue == -1) + { + return true; + } + } + + return false; + } + + private SqlExpression OptimizeCompareTo( + SqlBinaryExpression sqlBinaryExpression, + int intValue, + CaseExpression caseExpression) + { + var testLeft = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Left; + var testRight = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Right; + var operatorType = sqlBinaryExpression.Right is SqlConstantExpression + ? sqlBinaryExpression.OperatorType + : sqlBinaryExpression.OperatorType switch + { + ExpressionType.GreaterThan => ExpressionType.LessThan, + ExpressionType.GreaterThanOrEqual => ExpressionType.LessThanOrEqual, + ExpressionType.LessThan => ExpressionType.GreaterThan, + ExpressionType.LessThanOrEqual => ExpressionType.GreaterThanOrEqual, + _ => sqlBinaryExpression.OperatorType + }; + + if (operatorType == ExpressionType.NotEqual) + { + // CompareTo(a, b) != 0 -> a != b + // CompareTo(a, b) != 1 -> a <= b + // CompareTo(a, b) != -1 -> a >= b + return intValue switch + { + 0 => _sqlExpressionFactory.NotEqual(testLeft, testRight), + 1 => _sqlExpressionFactory.LessThanOrEqual(testLeft, testRight), + _ => _sqlExpressionFactory.GreaterThanOrEqual(testLeft, testRight), + }; + } + else if (operatorType == ExpressionType.GreaterThan) + { + // CompareTo(a, b) > 0 -> a > b + // CompareTo(a, b) > 1 -> false + // CompareTo(a, b) > -1 -> a >= b + return intValue switch + { + 0 => _sqlExpressionFactory.GreaterThan(testLeft, testRight), + 1 => _sqlExpressionFactory.Constant(false, sqlBinaryExpression.TypeMapping), + _ => _sqlExpressionFactory.GreaterThanOrEqual(testLeft, testRight), + }; + } + else if (operatorType == ExpressionType.GreaterThanOrEqual) + { + // CompareTo(a, b) >= 0 -> a >= b + // CompareTo(a, b) >= 1 -> a > b + // CompareTo(a, b) >= -1 -> true + return intValue switch + { + 0 => _sqlExpressionFactory.GreaterThanOrEqual(testLeft, testRight), + 1 => _sqlExpressionFactory.GreaterThan(testLeft, testRight), + _ => _sqlExpressionFactory.Constant(true, sqlBinaryExpression.TypeMapping), + }; + } + else if (operatorType == ExpressionType.LessThan) + { + // CompareTo(a, b) < 0 -> a < b + // CompareTo(a, b) < 1 -> a <= b + // CompareTo(a, b) < -1 -> false + return intValue switch + { + 0 => _sqlExpressionFactory.LessThan(testLeft, testRight), + 1 => _sqlExpressionFactory.LessThanOrEqual(testLeft, testRight), + _ => _sqlExpressionFactory.Constant(false, sqlBinaryExpression.TypeMapping), + }; + } + else + { + // operatorType == ExpressionType.LessThanOrEqual + // CompareTo(a, b) <= 0 -> a <= b + // CompareTo(a, b) <= 1 -> true + // CompareTo(a, b) <= -1 -> a < b + return intValue switch + { + 0 => _sqlExpressionFactory.LessThanOrEqual(testLeft, testRight), + 1 => _sqlExpressionFactory.Constant(true, sqlBinaryExpression.TypeMapping), + _ => _sqlExpressionFactory.LessThan(testLeft, testRight), + }; + } + } + /// /// Visits a and computes its nullability. /// @@ -883,7 +1030,6 @@ SqlExpression AddNullConcatenationProtection(SqlExpression argument, RelationalT /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlConstant( [NotNull] SqlConstantExpression sqlConstantExpression, bool allowOptimizedExpansion, out bool nullable) { @@ -893,6 +1039,7 @@ protected virtual SqlExpression VisitSqlConstant( return sqlConstantExpression; } + /// /// Visits a and computes its nullability. /// @@ -900,7 +1047,6 @@ protected virtual SqlExpression VisitSqlConstant( /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlFragment( [NotNull] SqlFragmentExpression sqlFragmentExpression, bool allowOptimizedExpansion, out bool nullable) { @@ -910,6 +1056,7 @@ protected virtual SqlExpression VisitSqlFragment( return sqlFragmentExpression; } + /// /// Visits a and computes its nullability. /// @@ -917,7 +1064,6 @@ protected virtual SqlExpression VisitSqlFragment( /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlFunction( [NotNull] SqlFunctionExpression sqlFunctionExpression, bool allowOptimizedExpansion, out bool nullable) { @@ -951,6 +1097,7 @@ protected virtual SqlExpression VisitSqlFunction( return sqlFunctionExpression.Update(instance, arguments); } + /// /// Visits a and computes its nullability. /// @@ -958,7 +1105,6 @@ protected virtual SqlExpression VisitSqlFunction( /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlParameter( [NotNull] SqlParameterExpression sqlParameterExpression, bool allowOptimizedExpansion, out bool nullable) { @@ -970,6 +1116,7 @@ protected virtual SqlExpression VisitSqlParameter( ? _sqlExpressionFactory.Constant(null, sqlParameterExpression.TypeMapping) : (SqlExpression)sqlParameterExpression; } + /// /// Visits a and computes its nullability. /// @@ -977,7 +1124,6 @@ protected virtual SqlExpression VisitSqlParameter( /// A bool value indicating if optimized expansion which considers null value as false value is allowed. /// A bool value indicating whether the sql expression is nullable. /// An optimized sql expression. - protected virtual SqlExpression VisitSqlUnary( [NotNull] SqlUnaryExpression sqlUnaryExpression, bool allowOptimizedExpansion, out bool nullable) { @@ -1163,6 +1309,32 @@ private SqlExpression OptimizeComparison( : _sqlExpressionFactory.Equal(left, right); } + var sqlConstantExpression = left as SqlConstantExpression ?? right as SqlConstantExpression; + var caseExpression = left as CaseExpression ?? right as CaseExpression; + + // generic CASE statement comparison optimization: + // (CASE + // WHEN condition1 THEN result1 + // WHEN condition2 THEN result2 + // WHEN ... + // WHEN conditionN THEN resultN) == result1 -> condition1 + if (sqlBinaryExpression.OperatorType == ExpressionType.Equal + && sqlConstantExpression != null + && sqlConstantExpression.Value != null + && caseExpression != null + && caseExpression.Operand == null) + { + var matchingCaseBlock = caseExpression.WhenClauses.FirstOrDefault(wc => sqlConstantExpression.Equals(wc.Result)); + if (matchingCaseBlock != null) + { + // we don't know if it's nullable since we don't store nullability of specific fragments + // so we must assume it's nullable + nullable = true; + + return matchingCaseBlock.Test; + } + } + nullable = false; return sqlBinaryExpression.Update(left, right); diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs index 220083489f5..19512dfbcd6 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs @@ -1258,6 +1258,21 @@ public virtual Task Nullable_string_FirstOrDefault_compared_to_nullable_string_L == e.NullableStringB.MaybeScalar(x => x.LastOrDefault()))); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Null_semantics_applied_to_CompareTo_equality(bool async) + { + await AssertQuery( + async, + ss => ss.Set().Where(e => e.NullableStringA.CompareTo(e.NullableStringB) == 0), + ss => ss.Set().Where(e => e.NullableStringA == e.NullableStringB)); + + await AssertQuery( + async, + ss => ss.Set().Where(e => e.NullableStringA.CompareTo(e.NullableStringB) != 0), + ss => ss.Set().Where(e => e.NullableStringA != e.NullableStringB)); + } + private string NormalizeDelimitersInRawString(string sql) => Fixture.TestStore.NormalizeDelimitersInRawString(sql); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index b3368267768..727db10feb8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -5248,20 +5248,11 @@ public override async Task Double_order_by_on_string_compare(bool async) { await base.Double_order_by_on_string_compare(async); - // issue #16092 AssertSql( @"SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId] FROM [Weapons] AS [w] ORDER BY CASE - WHEN (CASE - WHEN [w].[Name] = N'Marcus'' Lancer' THEN 0 - WHEN [w].[Name] > N'Marcus'' Lancer' THEN 1 - WHEN [w].[Name] < N'Marcus'' Lancer' THEN -1 - END = 0) AND CASE - WHEN [w].[Name] = N'Marcus'' Lancer' THEN 0 - WHEN [w].[Name] > N'Marcus'' Lancer' THEN 1 - WHEN [w].[Name] < N'Marcus'' Lancer' THEN -1 - END IS NOT NULL THEN CAST(1 AS bit) + WHEN [w].[Name] = N'Marcus'' Lancer' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END, [w].[Id]"); } @@ -5280,21 +5271,12 @@ public override async Task String_compare_with_null_conditional_argument(bool as { await base.String_compare_with_null_conditional_argument(async); - // issue #16092 AssertSql( @"SELECT [w0].[Id], [w0].[AmmunitionType], [w0].[IsAutomatic], [w0].[Name], [w0].[OwnerFullName], [w0].[SynergyWithId] FROM [Weapons] AS [w] LEFT JOIN [Weapons] AS [w0] ON [w].[SynergyWithId] = [w0].[Id] ORDER BY CASE - WHEN (CASE - WHEN [w0].[Name] = N'Marcus'' Lancer' THEN 0 - WHEN [w0].[Name] > N'Marcus'' Lancer' THEN 1 - WHEN [w0].[Name] < N'Marcus'' Lancer' THEN -1 - END = 0) AND CASE - WHEN [w0].[Name] = N'Marcus'' Lancer' THEN 0 - WHEN [w0].[Name] > N'Marcus'' Lancer' THEN 1 - WHEN [w0].[Name] < N'Marcus'' Lancer' THEN -1 - END IS NOT NULL THEN CAST(1 AS bit) + WHEN [w0].[Name] = N'Marcus'' Lancer' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END"); } @@ -5303,21 +5285,12 @@ public override async Task String_compare_with_null_conditional_argument2(bool a { await base.String_compare_with_null_conditional_argument2(async); - // issue #16092 AssertSql( @"SELECT [w0].[Id], [w0].[AmmunitionType], [w0].[IsAutomatic], [w0].[Name], [w0].[OwnerFullName], [w0].[SynergyWithId] FROM [Weapons] AS [w] LEFT JOIN [Weapons] AS [w0] ON [w].[SynergyWithId] = [w0].[Id] ORDER BY CASE - WHEN (CASE - WHEN N'Marcus'' Lancer' = [w0].[Name] THEN 0 - WHEN N'Marcus'' Lancer' > [w0].[Name] THEN 1 - WHEN N'Marcus'' Lancer' < [w0].[Name] THEN -1 - END = 0) AND CASE - WHEN N'Marcus'' Lancer' = [w0].[Name] THEN 0 - WHEN N'Marcus'' Lancer' > [w0].[Name] THEN 1 - WHEN N'Marcus'' Lancer' < [w0].[Name] THEN -1 - END IS NOT NULL THEN CAST(1 AS bit) + WHEN N'Marcus'' Lancer' = [w0].[Name] THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END"); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs index 6f93f0ff387..17e61ea4a62 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs @@ -174,105 +174,102 @@ public override async Task String_Compare_simple_zero(bool async) { await base.String_Compare_simple_zero(async); - // issue #16092 - // 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] = N'ALFKI'", - // // - // @"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] <> N'ALFKI'", - // // - // @"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] > N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] > N'ALFKI'", - // // - // @"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] <= N'ALFKI'"); + 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] = N'ALFKI'", + // + @"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] <> N'ALFKI'", + // + @"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] > N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] > N'ALFKI'", + // + @"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] <= N'ALFKI'"); } public override async Task String_Compare_simple_one(bool async) { await base.String_Compare_simple_one(async); - // issue #16092 - // 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] > N'ALFKI'", - // // - // @"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] < N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] >= N'ALFKI'", - // // - // @"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] >= N'ALFKI'"); + 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] > N'ALFKI'", + // + @"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] < N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] >= N'ALFKI'", + // + @"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] >= N'ALFKI'"); } public override async Task String_compare_with_parameter(bool async) { await base.String_compare_with_parameter(async); - // issue #16092 - // AssertSql( - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] > @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] < @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] <= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] <= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] >= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] >= @__customer_CustomerID_0"); + AssertSql( + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] > @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] < @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] <= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] <= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] >= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] >= @__customer_CustomerID_0"); } public override async Task String_Compare_simple_more_than_one(bool async) @@ -309,151 +306,146 @@ public override async Task String_Compare_nested(bool async) { await base.String_Compare_nested(async); - // issue #16092 - // 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] = N'M' + [c].[CustomerID]", - // // - // @"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] <> UPPER([c].[CustomerID])", - // // - // @"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] > REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])", - // // - // @"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] <= N'M' + [c].[CustomerID]", - // // - // @"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] > UPPER([c].[CustomerID])", - // // - // @"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] < REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])"); + 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] = (N'M' + [c].[CustomerID])", + // + @"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] <> UPPER([c].[CustomerID])", + // + @"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] > REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])", + // + @"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] <= (N'M' + [c].[CustomerID])", + // + @"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] > UPPER([c].[CustomerID])", + // + @"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] < REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])"); } public override async Task String_Compare_multi_predicate(bool async) { await base.String_Compare_multi_predicate(async); - // issue #16092 - // 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] >= N'ALFKI' AND [c].[CustomerID] < N'CACTU'", - // // - // @"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].[ContactTitle] = N'Owner' AND [c].[Country] <> N'USA'"); + 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] >= N'ALFKI') AND ([c].[CustomerID] < N'CACTU')", + // + @"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].[ContactTitle] = N'Owner') AND (([c].[Country] <> N'USA') OR [c].[Country] IS NULL)"); } public override async Task String_Compare_to_simple_zero(bool async) { await base.String_Compare_to_simple_zero(async); - // issue #16092 - // 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] = N'ALFKI'", - // // - // @"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] <> N'ALFKI'", - // // - // @"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] > N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] > N'ALFKI'", - // // - // @"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] <= N'ALFKI'"); + 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] = N'ALFKI'", + // + @"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] <> N'ALFKI'", + // + @"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] > N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] > N'ALFKI'", + // + @"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] <= N'ALFKI'"); } public override async Task String_Compare_to_simple_one(bool async) { await base.String_Compare_to_simple_one(async); - // issue #16092 - // 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] > N'ALFKI'", - // // - // @"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] < N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] <= N'ALFKI'", - // // - // @"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] >= N'ALFKI'", - // // - // @"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] >= N'ALFKI'"); + 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] > N'ALFKI'", + // + @"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] < N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] <= N'ALFKI'", + // + @"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] >= N'ALFKI'", + // + @"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] >= N'ALFKI'"); } public override async Task String_compare_to_with_parameter(bool async) { await base.String_compare_to_with_parameter(async); - // issue #16092 - // AssertSql( - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] > @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] < @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] <= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] <= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] >= @__customer_CustomerID_0", - // // - // @"@__customer_CustomerID_0='ALFKI' (Size = 4000) - - //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] >= @__customer_CustomerID_0"); + AssertSql( + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] > @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] < @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] <= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] <= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] >= @__customer_CustomerID_0", + // + @"@__customer_CustomerID_0='ALFKI' (Size = 5) (DbType = StringFixedLength) + +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] >= @__customer_CustomerID_0"); } public override async Task String_Compare_to_simple_more_than_one(bool async) @@ -490,132 +482,128 @@ public override async Task String_Compare_to_nested(bool async) { await base.String_Compare_to_nested(async); - //issue #16092 - // 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] = N'M' + [c].[CustomerID]", - // // - // @"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] <> UPPER([c].[CustomerID])", - // // - // @"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] > REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])", - // // - // @"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] <= N'M' + [c].[CustomerID]", - // // - // @"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] > UPPER([c].[CustomerID])", - // // - // @"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] < REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])"); + 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] = (N'M' + [c].[CustomerID])", + // + @"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] <> UPPER([c].[CustomerID])", + // + @"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] > REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])", + // + @"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] <= (N'M' + [c].[CustomerID])", + // + @"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] > UPPER([c].[CustomerID])", + // + @"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] < REPLACE(N'ALFKI', N'ALF', [c].[CustomerID])"); } public override async Task String_Compare_to_multi_predicate(bool async) { await base.String_Compare_to_multi_predicate(async); - // issue #16092 - // 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] >= N'ALFKI' AND [c].[CustomerID] < N'CACTU'", - // // - // @"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].[ContactTitle] = N'Owner' AND [c].[Country] <> N'USA'"); + 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] >= N'ALFKI') AND ([c].[CustomerID] < N'CACTU')", + // + @"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].[ContactTitle] = N'Owner') AND (([c].[Country] <> N'USA') OR [c].[Country] IS NULL)"); } public override async Task DateTime_Compare_to_simple_zero(bool async, bool compareTo) { await base.DateTime_Compare_to_simple_zero(async, compareTo); - // issue #16092 - // AssertSql( - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] = @__myDatetime_0", - // // - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] <> @__myDatetime_0", - // // - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] > @__myDatetime_0", - // // - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] <= @__myDatetime_0", - // // - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] > @__myDatetime_0", - // // - // @"@__myDatetime_0='1998-05-04T00:00:00' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderDate] <= @__myDatetime_0"); + AssertSql( + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderDate] = @__myDatetime_0", + // + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE ([o].[OrderDate] <> @__myDatetime_0) OR [o].[OrderDate] IS NULL", + // + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderDate] > @__myDatetime_0", + // + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderDate] <= @__myDatetime_0", + // + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderDate] > @__myDatetime_0", + // + @"@__myDatetime_0='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderDate] <= @__myDatetime_0"); } public override async Task Int_Compare_to_simple_zero(bool async) { await base.Int_Compare_to_simple_zero(async); - // issue #16092 - // AssertSql( - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] = @__orderId_0", - // // - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] <> @__orderId_0", - // // - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] > @__orderId_0", - // // - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] <= @__orderId_0", - // // - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] > @__orderId_0", - // // - // @"@__orderId_0='10250' - - //SELECT [c].[OrderID], [c].[CustomerID], [c].[EmployeeID], [c].[OrderDate] - //FROM [Orders] AS [c] - //WHERE [c].[OrderID] <= @__orderId_0"); + AssertSql( + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] = @__orderId_0", + // + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] <> @__orderId_0", + // + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] > @__orderId_0", + // + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] <= @__orderId_0", + // + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] > @__orderId_0", + // + @"@__orderId_0='10250' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] <= @__orderId_0"); } public override async Task Where_math_abs1(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs index 38ca2f378c1..9b1caffd38e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs @@ -1810,6 +1810,20 @@ FROM [Entities1] AS [e] WHERE (SUBSTRING([e].[NullableStringA], 1, 1) = SUBSTRING([e].[NullableStringB], LEN([e].[NullableStringB]), 1)) OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL)"); } + public override async Task Null_semantics_applied_to_CompareTo_equality(bool async) + { + await base.Null_semantics_applied_to_CompareTo_equality(async); + + AssertSql( + @"SELECT [e].[Id], [e].[BoolA], [e].[BoolB], [e].[BoolC], [e].[IntA], [e].[IntB], [e].[IntC], [e].[NullableBoolA], [e].[NullableBoolB], [e].[NullableBoolC], [e].[NullableIntA], [e].[NullableIntB], [e].[NullableIntC], [e].[NullableStringA], [e].[NullableStringB], [e].[NullableStringC], [e].[StringA], [e].[StringB], [e].[StringC] +FROM [Entities1] AS [e] +WHERE ([e].[NullableStringA] = [e].[NullableStringB]) OR ([e].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL)", + // + @"SELECT [e].[Id], [e].[BoolA], [e].[BoolB], [e].[BoolC], [e].[IntA], [e].[IntB], [e].[IntC], [e].[NullableBoolA], [e].[NullableBoolB], [e].[NullableBoolC], [e].[NullableIntA], [e].[NullableIntB], [e].[NullableIntC], [e].[NullableStringA], [e].[NullableStringB], [e].[NullableStringC], [e].[StringA], [e].[StringB], [e].[StringC] +FROM [Entities1] AS [e] +WHERE (([e].[NullableStringA] <> [e].[NullableStringB]) OR ([e].[NullableStringA] IS NULL OR [e].[NullableStringB] IS NULL)) AND ([e].[NullableStringA] IS NOT NULL OR [e].[NullableStringB] IS NOT NULL)"); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected);