Fixes generation of broken SQL on multiple skip/take calls #23670
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've spent some time investigating how to fix #21026, because our users keep hitting this bug over and over again.
To make analysis easier, I've simplified the repoduction scenario a bit.
The next query:
produces the following when using SQL Server:
This fails with the below error when sent to SQL Server LocalDb:
Looking at the EF Core source code, I found that
SelectExpression.PushdownIntoSubquery
always uses the hardcoded alias 't' (here), which is called multiple times. This makes it impossible for the LEFT JOIN generator to distinguish between [t] and what is later renamed to [t0] byTableAliasUniquifyingExpressionVisitor
.I believe I've fixed this bug by assigning a unique alias each time
SelectExpression.PushdownIntoSubquery
executes.The downside is that this changes the generated names in SQL, breaking lots of other tests (queries are built from the inside out).
When applying the changes from this PR, the next SQL is generated, which looks correct to me:
An interesting side effect of my change is that the deepest SELECT no longer selects BlogId and Title, which were not needed anyway.
I also noticed my test succeeds when run in isolation, but fails when running all tests in the file. The alias numbers change. I'm probably generating them at the wrong scope.
As I'm fairly new to this codebase, I'm sure there must a better way to solve this. Any pointers are highly appreciated! I'll add doc-comments etc. once I know I'm on the right track.
Closes #21026.