-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Redo SQL tree pruning #32672
Redo SQL tree pruning #32672
Conversation
@@ -21,6 +21,8 @@ public class SqlServerQuerySqlGenerator : QuerySqlGenerator | |||
private readonly ISqlGenerationHelper _sqlGenerationHelper; | |||
private readonly int _sqlServerCompatibilityLevel; | |||
|
|||
private bool _withinTable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes for SQL Server generation are unfortunate and tricky...
SQL Server is very strict and does not allow a projection without an alias within a table subquery (SELECT ... FROM (SELECT 1 ...))
); we already had special logic for generating 1 AS empty
to work around this, but the logic for when to do this was incomplete. The pruning introduced in this PR caused selects within set operations to also possibly get their projection completely trimmed away, but our logic didn't catch that (this was an already-existing, possibly latent bug).
As a result, we need to do visitor state hacks to detect when the empty projection is directly in a subquery table, to generate AS empty
only when needed.
public override Task Update_non_main_table_in_entity_with_entity_splitting(bool async) | ||
=> Assert.ThrowsAnyAsync<Exception>( | ||
() => base.Update_non_main_table_in_entity_with_entity_splitting(async)); | ||
public override async Task Update_non_main_table_in_entity_with_entity_splitting(bool async) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix for #31407
@@ -42,9 +42,6 @@ public override async Task Delete_where_using_hierarchy(bool async) | |||
WHERE ( | |||
SELECT COUNT(*) | |||
FROM [Animals] AS [a] | |||
LEFT JOIN [Birds] AS [b] ON [a].[Id] = [b].[Id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We weren't doing any pruning in subqueries that weren't table subqueries (this one is a scalar subquery inside the predicate).
SELECT JSON_VALUE([o].[value], '$.OwnedReferenceLeaf.SomethingSomething') AS [c], [o].[key], CAST(JSON_VALUE([o].[value], '$.Date') AS datetime2) AS [c0] | ||
FROM OPENJSON([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') AS [o] | ||
ORDER BY CAST(JSON_VALUE([o].[value], '$.Date') AS datetime2) DESC | ||
SELECT JSON_VALUE([o].[OwnedReferenceLeaf], '$.SomethingSomething') AS [c], [o].[Date] AS [c0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "expansion" from WITH-less OPENJSON to WITH-ful is actually an improvement; an upcoming PR will also prune unreferenced columns from the WITH column list.
@@ -331,7 +331,7 @@ public virtual async Task Ordered_array_of_string() | |||
WHERE ( | |||
SELECT COUNT(*) | |||
FROM ( | |||
SELECT [s].[value], [s].[key], CAST([s].[key] AS int) AS [c] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maumar we discussed pruning these - so here we go :) I'm not sure any more if we opened an issue to track this (couldn't find one in a quick search)
@@ -2556,21 +2556,21 @@ public override async Task Concat_anonymous_with_count(bool async) | |||
""" | |||
SELECT COUNT(*) | |||
FROM ( | |||
SELECT [t].[Nickname], [t].[SquadId], [t].[AssignedCityName], [t].[CityOfBirthName], [t].[FullName], [t].[HasSoulPatch], [t].[LeaderNickname], [t].[LeaderSquadId], [t].[Rank], [t].[Discriminator], [t].[Nickname] AS [Name] | |||
SELECT 1 AS empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice example where having COUNT(*) at the top causes all projections inside to get pruned
Closes dotnet#31083 Fixes dotnet#31407
@ajcvickers you may be interested in taking a look, this is query stuff but relatively scoped to a specific problem etc.
Two additional pruning-related PRs also coming up based on this one.
Closes #31083
Fixes #31407