Skip to content

Commit e6eef43

Browse files
authored
[release/10.0] Fix parameter counting when type mapping differs. (#37333)
1 parent a7394d3 commit e6eef43

File tree

8 files changed

+123
-1
lines changed

8 files changed

+123
-1
lines changed

src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,10 @@ public class ParametersCounter(
416416
ReferenceEquals(lhs, rhs)
417417
|| (lhs is not null && rhs is not null
418418
&& lhs.InvariantName == rhs.InvariantName
419+
&& lhs.Type == rhs.Type
420+
&& lhs.TypeMapping == rhs.TypeMapping
419421
&& lhs.TranslationMode == rhs.TranslationMode),
420-
x => HashCode.Combine(x.InvariantName, x.TranslationMode)));
422+
x => HashCode.Combine(x.InvariantName, x.Type, x.TypeMapping, x.TranslationMode)));
421423

422424
private readonly HashSet<QueryParameterExpression> _visitedQueryParameters =
423425
new(EqualityComparer<QueryParameterExpression>.Create(

test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,10 @@ public override Task Parameter_collection_Count_with_huge_number_of_values_over_
851851
public override Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_same_parameter()
852852
=> base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_same_parameter();
853853

854+
// nothing to test here
855+
public override Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
856+
=> base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
857+
854858
// nothing to test here
855859
public override Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_mixed_parameters_constants()
856860
=> base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_mixed_parameters_constants();
@@ -867,6 +871,10 @@ public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_
867871
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_same_parameter()
868872
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_same_parameter();
869873

874+
// nothing to test here
875+
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
876+
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
877+
870878
// nothing to test here
871879
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
872880
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,26 @@ public virtual Task Parameter_collection_Count_with_huge_number_of_values_over_5
578578
.Where(c => extra.Count(i => i > c.Id) > 0));
579579
}
580580

581+
[ConditionalFact]
582+
public virtual Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
583+
{
584+
if (NumberOfValuesForHugeParameterCollectionTests is null)
585+
{
586+
return Task.CompletedTask;
587+
}
588+
589+
var extra = Enumerable.Range(1000, (int)NumberOfValuesForHugeParameterCollectionTests / 3);
590+
var ids = new[] { 2, 999 };
591+
592+
// Id will have a different type mapping here.
593+
// Very specific, kind of fragile, but at least something.
594+
// More info efcore#37185.
595+
return AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>()
596+
.Where(c => ids.Count(i => i > c.Id) > 0)
597+
.Where(c => extra.Count(i => i > c.Id) > 0)
598+
.Where(c => extra.Count(i => i > c.Int) > 0));
599+
}
600+
581601
[ConditionalFact]
582602
public virtual Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants()
583603
{
@@ -733,6 +753,30 @@ await AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>()
733753
.Where(c => !extra.Contains(c.Int)));
734754
}
735755

756+
[ConditionalFact]
757+
public virtual async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
758+
{
759+
if (NumberOfValuesForHugeParameterCollectionTests is null)
760+
{
761+
return;
762+
}
763+
764+
var extra = Enumerable.Range(10, (int)NumberOfValuesForHugeParameterCollectionTests / 3).Append(1);
765+
var ints = new[] { 10, 999 };
766+
767+
// Id will have a different type mapping here.
768+
// Very specific, kind of fragile, but at least something.
769+
// More info efcore#37185.
770+
await AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>()
771+
.Where(c => ints.Contains(c.Int))
772+
.Where(c => extra.Contains(c.Int))
773+
.Where(c => extra.Contains(c.Id)));
774+
await AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>()
775+
.Where(c => !ints.Contains(c.Int))
776+
.Where(c => !extra.Contains(c.Int))
777+
.Where(c => !extra.Contains(c.Id)));
778+
}
779+
736780
[ConditionalFact]
737781
public virtual async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
738782
{

test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,13 @@ public override async Task Parameter_collection_Count_with_huge_number_of_values
862862
Assert.Contains("@ids2=", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
863863
}
864864

865+
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
866+
{
867+
await base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
868+
869+
Assert.Contains("VALUES (2)", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
870+
}
871+
865872
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants()
866873
{
867874
await base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants();
@@ -903,6 +910,14 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n
903910
Assert.Contains("@ints2=", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
904911
}
905912

913+
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
914+
{
915+
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
916+
917+
Assert.DoesNotContain("OPENJSON", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
918+
Assert.DoesNotContain("OPENJSON", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
919+
}
920+
906921
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
907922
{
908923
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,13 @@ public override async Task Parameter_collection_Count_with_huge_number_of_values
870870
Assert.Contains("@ids2=", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
871871
}
872872

873+
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
874+
{
875+
await base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
876+
877+
Assert.Contains("OPENJSON(@ids) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
878+
}
879+
873880
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants()
874881
{
875882
await base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants();
@@ -911,6 +918,14 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n
911918
Assert.Contains("@ints2=", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
912919
}
913920

921+
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
922+
{
923+
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
924+
925+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
926+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
927+
}
928+
914929
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
915930
{
916931
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ public override async Task Parameter_collection_Count_with_huge_number_of_values
117117
Assert.Contains("@ids2=", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
118118
}
119119

120+
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
121+
{
122+
await base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
123+
124+
Assert.Contains("OPENJSON(@ids) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
125+
}
126+
120127
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants()
121128
{
122129
await base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants();
@@ -158,6 +165,14 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n
158165
Assert.Contains("@ints2=", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
159166
}
160167

168+
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
169+
{
170+
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
171+
172+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
173+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
174+
}
175+
161176
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
162177
{
163178
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,13 @@ public override async Task Parameter_collection_Count_with_huge_number_of_values
893893
Assert.Contains("@ids2=", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
894894
}
895895

896+
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
897+
{
898+
await base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
899+
900+
Assert.Contains("OPENJSON(@ids) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
901+
}
902+
896903
public override async Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants()
897904
{
898905
await base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_forced_constants();
@@ -934,6 +941,14 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n
934941
Assert.Contains("@ints2=", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
935942
}
936943

944+
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
945+
{
946+
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
947+
948+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
949+
Assert.Contains("OPENJSON(@ints) WITH ([value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal);
950+
}
951+
937952
public override async Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
938953
{
939954
await base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,10 @@ public override Task Parameter_collection_Count_with_huge_number_of_values_over_
875875
public override Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_same_parameter()
876876
=> base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_same_parameter();
877877

878+
// nothing to test here
879+
public override Task Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
880+
=> base.Parameter_collection_Count_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
881+
878882
// nothing to test here
879883
public override Task Parameter_collection_Count_with_huge_number_of_values_over_5_operations_mixed_parameters_constants()
880884
=> base.Parameter_collection_Count_with_huge_number_of_values_over_5_operations_mixed_parameters_constants();
@@ -891,6 +895,10 @@ public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_
891895
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_same_parameter()
892896
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_same_parameter();
893897

898+
// nothing to test here
899+
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping()
900+
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_2_operations_same_parameter_different_type_mapping();
901+
894902
// nothing to test here
895903
public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants()
896904
=> base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_forced_constants();

0 commit comments

Comments
 (0)