Skip to content
Open
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
18 changes: 16 additions & 2 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -651,8 +651,15 @@ protected virtual Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpress
/// <param name="sqlConstantExpression">The <see cref="SqlConstantExpression" /> for which to generate SQL.</param>
protected virtual Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression)
{
if (sqlConstantExpression.TypeMapping is null)
{
throw new UnreachableException(
"SqlConstantExpression has no type mapping. "
+ "Please file a bug report at https://github.com/dotnet/efcore.");
}

_relationalCommandBuilder
.Append(sqlConstantExpression.TypeMapping!.GenerateSqlLiteral(sqlConstantExpression.Value), sqlConstantExpression.IsSensitive);
.Append(sqlConstantExpression.TypeMapping.GenerateSqlLiteral(sqlConstantExpression.Value), sqlConstantExpression.IsSensitive);

return sqlConstantExpression;
}
Expand All @@ -663,6 +670,13 @@ protected virtual Expression VisitSqlConstant(SqlConstantExpression sqlConstantE
/// <param name="sqlParameterExpression">The <see cref="SqlParameterExpression" /> for which to generate SQL.</param>
protected virtual Expression VisitSqlParameter(SqlParameterExpression sqlParameterExpression)
{
if (sqlParameterExpression.TypeMapping is null)
{
throw new UnreachableException(
$"SqlParameterExpression '{sqlParameterExpression.Name}' has no type mapping. "
+ "Please file a bug report at https://github.com/dotnet/efcore.");
}

var name = sqlParameterExpression.Name;

// Only add the parameter to the command the first time we see its (non-invariant) name, even though we may need to add its
Expand All @@ -672,7 +686,7 @@ protected virtual Expression VisitSqlParameter(SqlParameterExpression sqlParamet
_relationalCommandBuilder.AddParameter(
sqlParameterExpression.InvariantName,
_sqlGenerationHelper.GenerateParameterName(name),
sqlParameterExpression.TypeMapping!,
sqlParameterExpression.TypeMapping,
sqlParameterExpression.IsNullable);
_parameterNames.Add(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,14 @@ protected virtual ValuesExpression ApplyTypeMappingsOnValuesExpression(ValuesExp
var value = rowValue.Values[j];

if (value.TypeMapping is null
&& inferredTypeMappings[j] is { } inferredTypeMapping)
// Fall back to the default type mapping for the CLR type when no type mapping was inferred
// from usage context (e.g. SelectMany where the value column isn't referenced).
&& (inferredTypeMappings[j]
?? RelationalDependencies.TypeMappingSource.FindMapping(
value.Type, QueryCompilationContext.Model))
is { } resolvedTypeMapping)
{
value = _sqlExpressionFactory.ApplyTypeMapping(value, inferredTypeMapping);
value = _sqlExpressionFactory.ApplyTypeMapping(value, resolvedTypeMapping);
}

// We currently add explicit conversions on the first row (but not to the _ord column), to ensure that the inferred
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@ OFFSET 0 LIMIT 2
""");
}

public override async Task Inline_collection_SelectMany_with_unreferenced_collection_value()
=> await Assert.ThrowsAsync<InvalidOperationException>(
() => base.Inline_collection_SelectMany_with_unreferenced_collection_value());

// https://github.com/Azure/azure-cosmos-db-emulator-docker/issues/287 (Aggregates over subqueries return null result set)
[CosmosCondition(CosmosCondition.IsNotLinuxEmulator)]
public override async Task Parameter_collection_Count()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ public virtual async Task Inline_collection_in_query_filter()
Assert.Equal(2, result.Id);
}

[ConditionalFact] // #38285
public virtual Task Inline_collection_SelectMany_with_unreferenced_collection_value()
Comment thread
roji marked this conversation as resolved.
=> AssertQuery(
ss => ss.Set<PrimitiveCollectionsEntity>().SelectMany(e => new[] { "a", "b" }.Select(k => e)));

[ConditionalFact]
public virtual Task Parameter_collection_Count()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,18 @@ SELECT COUNT(*)
""");
}

public override async Task Inline_collection_SelectMany_with_unreferenced_collection_value()
{
await base.Inline_collection_SelectMany_with_unreferenced_collection_value();

AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId]
FROM [PrimitiveCollectionsEntity] AS [p]
CROSS APPLY (VALUES (CAST(N'a' AS nvarchar(max))), (N'b')) AS [v]([Value])
""");
}

public override async Task Parameter_collection_Count()
{
await base.Parameter_collection_Count();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,18 @@ SELECT COUNT(*)
""");
}

public override async Task Inline_collection_SelectMany_with_unreferenced_collection_value()
{
await base.Inline_collection_SelectMany_with_unreferenced_collection_value();

AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId]
FROM [PrimitiveCollectionsEntity] AS [p]
CROSS APPLY (VALUES (CAST(N'a' AS nvarchar(max))), (N'b')) AS [v]([Value])
""");
}

public override async Task Parameter_collection_Count()
{
await base.Parameter_collection_Count();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,18 @@ SELECT COUNT(*)
""");
}

public override async Task Inline_collection_SelectMany_with_unreferenced_collection_value()
{
await base.Inline_collection_SelectMany_with_unreferenced_collection_value();

AssertSql(
"""
SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId]
FROM [PrimitiveCollectionsEntity] AS [p]
CROSS APPLY (VALUES (CAST(N'a' AS nvarchar(max))), (N'b')) AS [v]([Value])
""");
}

public override async Task Parameter_collection_Count()
{
await base.Parameter_collection_Count();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,12 @@ public override async Task Column_collection_SelectMany()
SqliteStrings.ApplyNotSupported,
(await Assert.ThrowsAsync<InvalidOperationException>(() => base.Column_collection_SelectMany())).Message);

public override async Task Inline_collection_SelectMany_with_unreferenced_collection_value()
=> Assert.Equal(
SqliteStrings.ApplyNotSupported,
(await Assert.ThrowsAsync<InvalidOperationException>(
() => base.Inline_collection_SelectMany_with_unreferenced_collection_value())).Message);

public override async Task Column_collection_SelectMany_with_filter()
=> Assert.Equal(
SqliteStrings.ApplyNotSupported,
Expand Down
Loading