Workaround for ValuesExpression (#222)

* Implement a workaround for the VALUES expression in a SELECT
pull/224/head
Christopher Jolly 2 years ago committed by GitHub
parent 8d6b893c62
commit d94c8a758e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -751,6 +751,71 @@ namespace EntityFrameworkCore.Jet.Query.Sql.Internal
return crossJoinExpression;
}
private Expression VisitRowValuePrivate(RowValueExpression rowValueExpression, IReadOnlyList<string> columnNames)
{
var values = rowValueExpression.Values;
var count = values.Count;
for (var i = 0; i < count; i++)
{
if (i > 0)
{
Sql.Append(", ");
}
Visit(values[i]);
Sql.Append(" AS ");
Sql.Append(_sqlGenerationHelper.DelimitIdentifier(columnNames[i]));
}
return rowValueExpression;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitValues(ValuesExpression valuesExpression)
{
base.VisitValues(valuesExpression);
return valuesExpression;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override void GenerateValues(ValuesExpression valuesExpression)
{
if (valuesExpression.RowValues.Count == 0)
{
throw new InvalidOperationException(RelationalStrings.EmptyCollectionNotSupportedAsInlineQueryRoot);
}
var rowValues = valuesExpression.RowValues;
for (var i = 0; i < rowValues.Count; i++)
{
Sql.Append("SELECT ");
VisitRowValuePrivate(valuesExpression.RowValues[i], valuesExpression.ColumnNames);
GeneratePseudoFromClause();
var alias = valuesExpression.Alias;
Sql.Append(" AS ");
Sql.Append(_sqlGenerationHelper.DelimitIdentifier(alias + "_" + i));
if (i != rowValues.Count - 1)
{
Sql.AppendLine();
Sql.AppendLine("UNION");
}
}
}
/// <summary>Generates the TOP part of the SELECT statement,</summary>
/// <param name="selectExpression"> The select expression. </param>
protected override void GenerateTop(SelectExpression selectExpression)

@ -15226,6 +15226,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.I
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_two_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_zero_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_zero_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_one_value(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_one_value(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_three_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_three_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_two_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_two_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_zero_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_zero_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Except_column_collection(async: False)

@ -16390,6 +16390,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.I
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_two_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_zero_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Contains_with_zero_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_one_value(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_one_value(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_three_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_three_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_two_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_two_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_zero_values(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Count_with_zero_values(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.PrimitiveCollectionsQueryJetTest.Inline_collection_Except_column_collection(async: False)

@ -77,13 +77,14 @@ WHERE `p`.`NullableInt` IS NULL OR `p`.`NullableInt` = 999
await base.Inline_collection_Count_with_one_value(async);
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].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
"""
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`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE (
SELECT COUNT(*)
FROM (VALUES (CAST(2 AS int))) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
FROM (SELECT CLNG(2) AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_0`) AS `v`
WHERE `v`.`Value` > `p`.`Id`) = 1
""");
}
@ -92,13 +93,17 @@ WHERE (
await base.Inline_collection_Count_with_two_values(async);
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].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
"""
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`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE (
SELECT COUNT(*)
FROM (VALUES (CAST(2 AS int)), (999)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
FROM (SELECT CLNG(2) AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_0`
UNION
SELECT 999 AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_1`) AS `v`
WHERE `v`.`Value` > `p`.`Id`) = 1
""");
}
@ -107,13 +112,20 @@ WHERE (
await base.Inline_collection_Count_with_three_values(async);
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].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
"""
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`.`String`, `p`.`Strings`
FROM `PrimitiveCollectionsEntity` AS `p`
WHERE (
SELECT COUNT(*)
FROM (VALUES (CAST(2 AS int)), (999), (1000)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 2
FROM (SELECT CLNG(2) AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_0`
UNION
SELECT 999 AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_1`
UNION
SELECT 1000 AS `Value`
FROM (SELECT COUNT(*) FROM `#Dual`) AS `v_2`) AS `v`
WHERE `v`.`Value` > `p`.`Id`) = 2
""");
}

Loading…
Cancel
Save