Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use correct parameter in query based on type mapping #29650

Merged
1 commit merged into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -598,21 +598,33 @@ protected override Expression VisitSqlParameter(SqlParameterExpression sqlParame
var invariantName = sqlParameterExpression.Name;
var parameterName = sqlParameterExpression.Name;

if (_relationalCommandBuilder.Parameters
.All(
p => p.InvariantName != parameterName
|| (p is TypeMappedRelationalParameter typeMappedRelationalParameter
&& (typeMappedRelationalParameter.RelationalTypeMapping.StoreType != sqlParameterExpression.TypeMapping!.StoreType
|| typeMappedRelationalParameter.RelationalTypeMapping.Converter
!= sqlParameterExpression.TypeMapping!.Converter))))
// Try to see if a parameter already exists - if so, just integrate the same placeholder into the SQL instead of sending the same
// data twice.
// Note that if the type mapping differs, we do send the same data twice (e.g. the same string may be sent once as Unicode, once as
// non-Unicode).
var parameter = _relationalCommandBuilder.Parameters.FirstOrDefault(
p =>
p.InvariantName == parameterName
&& p is TypeMappedRelationalParameter typeMappedRelationalParameter
&& string.Equals(
typeMappedRelationalParameter.RelationalTypeMapping.StoreType, sqlParameterExpression.TypeMapping!.StoreType,
StringComparison.OrdinalIgnoreCase)
&& typeMappedRelationalParameter.RelationalTypeMapping.Converter == sqlParameterExpression.TypeMapping!.Converter);

if (parameter is null)
{
parameterName = GetUniqueParameterName(parameterName);

_relationalCommandBuilder.AddParameter(
invariantName,
_sqlGenerationHelper.GenerateParameterName(parameterName),
sqlParameterExpression.TypeMapping!,
sqlParameterExpression.IsNullable);
}
else
{
parameterName = ((TypeMappedRelationalParameter)parameter).Name;
}

_relationalCommandBuilder
.Append(_sqlGenerationHelper.GenerateParameterNamePlaceholder(parameterName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public virtual Task Parameter_used_multiple_times_take_appropriate_inferred_type
var place = "Seattle";
return AssertQuery(
async,
ss => ss.Set<City>().Where(e => e.Nation == place || e.Location == place));
ss => ss.Set<City>().Where(e => e.Nation == place || e.Location == place || e.Location == place));
}

public override async Task Correlated_collection_with_distinct_not_projecting_identifier_column_also_projecting_complex_expressions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9413,7 +9413,7 @@ public override async Task Parameter_used_multiple_times_take_appropriate_inferr

SELECT [c].[Name], [c].[Location], [c].[Nation]
FROM [Cities] AS [c]
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1 OR [c].[Location] = @__place_0_1
""");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4779,7 +4779,7 @@ public override async Task Comparing_to_fixed_string_parameter(bool async)

SELECT [c].[CustomerID]
FROM [Customers] AS [c]
WHERE @__prefix_0 = N'' OR LEFT([c].[CustomerID], LEN(@__prefix_0_1)) = @__prefix_0
WHERE @__prefix_0 = N'' OR LEFT([c].[CustomerID], LEN(@__prefix_0_1)) = @__prefix_0_1
""");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override async Task Count_query(bool async)

SELECT COUNT(*)
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -47,7 +47,7 @@ public override async Task Materialized_query(bool async)

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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -63,7 +63,7 @@ public override async Task Find(bool async)

SELECT TOP(1) [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 (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0) AND [c].[CustomerID] = @__p_0
WHERE (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1) AND [c].[CustomerID] = @__p_0
""");
}

Expand All @@ -78,7 +78,7 @@ public override async Task Materialized_query_parameter(bool async)

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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -93,7 +93,7 @@ public override async Task Materialized_query_parameter_new_context(bool async)

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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""",
//
"""
Expand All @@ -102,7 +102,7 @@ public override async Task Materialized_query_parameter_new_context(bool async)

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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -117,7 +117,7 @@ public override async Task Projection_query_parameter(bool async)

SELECT [c].[CustomerID]
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -132,7 +132,7 @@ public override async Task Projection_query(bool async)

SELECT [c].[CustomerID]
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -153,11 +153,11 @@ public override async Task Include_query(bool async)
LEFT JOIN (
SELECT [c0].[CustomerID], [c0].[CompanyName]
FROM [Customers] AS [c0]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c0].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c0].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [o].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
ORDER BY [c].[CustomerID], [t0].[OrderID]
""");
}
Expand Down Expand Up @@ -189,7 +189,7 @@ public override async Task Included_many_to_one_query(bool async)
LEFT JOIN (
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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [o].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
""");
Expand All @@ -213,7 +213,7 @@ public override async Task Project_reference_that_itself_has_query_filter_with_a
LEFT JOIN (
SELECT [c].[CustomerID], [c].[CompanyName]
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_1 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_1_1)) = @__ef_filter__TenantPrefix_1
WHERE @__ef_filter__TenantPrefix_1 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_1_1)) = @__ef_filter__TenantPrefix_1_1
) AS [t] ON [o0].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
) AS [t0] ON [o].[OrderID] = [t0].[OrderID]
Expand All @@ -239,7 +239,7 @@ public override async Task Navs_query(bool async)
LEFT JOIN (
SELECT [c0].[CustomerID], [c0].[CompanyName]
FROM [Customers] AS [c0]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c0].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c0].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [o].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID]
Expand All @@ -252,13 +252,13 @@ public override async Task Navs_query(bool async)
LEFT JOIN (
SELECT [c1].[CustomerID], [c1].[CompanyName]
FROM [Customers] AS [c1]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c1].[CompanyName], LEN(@__ef_filter__TenantPrefix_0)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c1].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t3] ON [o1].[CustomerID] = [t3].[CustomerID]
WHERE ([t3].[CustomerID] IS NOT NULL) AND ([t3].[CompanyName] IS NOT NULL)
) AS [t2] ON [o0].[OrderID] = [t2].[OrderID]
WHERE [o0].[Quantity] > @__ef_filter___quantity_1
) AS [t1] ON [t0].[OrderID] = [t1].[OrderID]
WHERE (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0)) = @__ef_filter__TenantPrefix_0) AND [t1].[Discount] < CAST(10 AS real)
WHERE (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1) AND [t1].[Discount] < CAST(10 AS real)
""");
}

Expand All @@ -281,7 +281,7 @@ public void FromSql_is_composed()
FROM (
select * from Customers
) AS [m]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([m].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([m].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
""");
}

Expand All @@ -307,7 +307,7 @@ public void FromSql_is_composed_when_filter_has_navigation()
LEFT JOIN (
SELECT [c].[CustomerID], [c].[CompanyName]
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [m].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
""");
Expand All @@ -325,7 +325,7 @@ public override void Compiled_query()

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 (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0) AND [c].[CustomerID] = @__customerID
WHERE (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1) AND [c].[CustomerID] = @__customerID
""",
//
"""
Expand All @@ -335,7 +335,7 @@ public override void Compiled_query()

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 (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0) AND [c].[CustomerID] = @__customerID
WHERE (@__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1) AND [c].[CustomerID] = @__customerID
""");
}

Expand All @@ -353,7 +353,7 @@ public override async Task Entity_Equality(bool async)
LEFT JOIN (
SELECT [c].[CustomerID], [c].[CompanyName]
FROM [Customers] AS [c]
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [o].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
""");
Expand All @@ -380,7 +380,7 @@ public override async Task Included_many_to_one_query2(bool async)
LEFT JOIN (
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 @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0
WHERE @__ef_filter__TenantPrefix_0 = N'' OR LEFT([c].[CompanyName], LEN(@__ef_filter__TenantPrefix_0_1)) = @__ef_filter__TenantPrefix_0_1
) AS [t] ON [o].[CustomerID] = [t].[CustomerID]
WHERE ([t].[CustomerID] IS NOT NULL) AND ([t].[CompanyName] IS NOT NULL)
""");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11939,7 +11939,7 @@ public override async Task Parameter_used_multiple_times_take_appropriate_inferr

SELECT [c].[Name], [c].[Location], [c].[Nation]
FROM [Cities] AS [c]
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1 OR [c].[Location] = @__place_0_1
""");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10225,7 +10225,7 @@ public override async Task Parameter_used_multiple_times_take_appropriate_inferr

SELECT [c].[Name], [c].[Location], [c].[Nation]
FROM [Cities] AS [c]
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1 OR [c].[Location] = @__place_0_1
""");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3252,7 +3252,7 @@ public override async Task Parameter_used_multiple_times_take_appropriate_inferr

SELECT [c].[Name], [c].[Location], [c].[Nation], [c].[PeriodEnd], [c].[PeriodStart]
FROM [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c]
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1
WHERE [c].[Nation] = @__place_0 OR [c].[Location] = @__place_0_1 OR [c].[Location] = @__place_0_1
""");
}

Expand Down Expand Up @@ -9794,7 +9794,7 @@ public override async Task EF_Property_based_Include_navigation_on_derived_type(
""");
}

// Sequence contains no elements due to temporal filter
// Sequence contains no elements due to temporal filter
public override Task ElementAt_basic_with_OrderBy(bool async)
=> Task.CompletedTask;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2903,7 +2903,7 @@ public override async Task Parameter_used_multiple_times_take_appropriate_inferr

SELECT "c"."Name", "c"."Location", "c"."Nation"
FROM "Cities" AS "c"
WHERE "c"."Nation" = @__place_0 OR "c"."Location" = @__place_0
WHERE "c"."Nation" = @__place_0 OR "c"."Location" = @__place_0 OR "c"."Location" = @__place_0
""");
}

Expand Down