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

Relational: Translate SelectMany #17077

Merged
merged 2 commits into from
Aug 13, 2019
Merged

Relational: Translate SelectMany #17077

merged 2 commits into from
Aug 13, 2019

Conversation

smitpatel
Copy link
Contributor

@smitpatel smitpatel commented Aug 10, 2019

SelectMany in linq look something like following (second clause is considered the collection selector)

from c in cs
from o in c.Orders
select....

Following are the translations of SelectMany

Unrelated collection selector

from c in cs
from o in os

Generates CROSS JOIN

Correlated collection selector with correlation being a predicate

from c in cs
from o in os.Where(o => o.CustomerID == c.CustomerID)

Such predicate can be lifted and used in generating a join. So this query generates JOIN.
If collection selector ends with DefaultIfEmpty then it is LEFT JOIN.

Correlated collection selector with correlation not a predicate

from c in cs
from o in os.Select(o => c.City)

Since we cannot generate a join predicate here, this translates to CROSS APPLY.
If collection selector ends with DefaultIfEmpty then it is OUTER APPLY.

  • Add support for Cross Apply
  • Add Support for Outer Apply
  • Convert Cross Apply to Inner Join when possible
  • Convert Outer Apply to Left Join when possible
  • Add translation for DefaultIfEmpty
  • Add translation for both overloads of SelectMany
  • Handle DefaultIfEmpty & SelectMany without collectionSelector in Navigation Expansion
  • Ensure columns are in projection when generating join predicate from a correlated subquery

Currently there are no tests for Cross/Outer Apply.
Our earlier Cross Apply got converted to join. N+1 evaluation tests are disabled right now, which would generate Cross Apply.
We never supported Outer Apply in past.

Resolves #15711
Resolves #12567
Resolves #12572
Resolves #12872
Resolves #16330
Resolves #15081
Resolves #16989

Re-enable tests for #12449

@ajcvickers
Copy link
Member

@maumar Please make it a priority to review this when you get in. (You were nominated in triage! 🚎)

@maumar maumar mentioned this pull request Aug 12, 2019
SelectMany in linq look something like following (second clause is considered the collection selector)
```C#
from c in cs
from o in c.Orders
select....
```
Following are the translations of SelectMany

Unrelated collection selector
```C#
from c in cs
from o in os
```
Generates CROSS JOIN

Correlated collection selector with correlation being a predicate
```C#
from c in cs
from o in os.Where(o => o.CustomerID == c.CustomerID)
```
Such predicate can be lifted and used in generating a join. So this query generates JOIN.
If collection selector ends with DefaultIfEmpty then it is LEFT JOIN.

Correlated collection selector with correlation not a predicate
```C#
from c in cs
from o in os.Select(o => c.City)
```
Since we cannot generate a join predicate here, this translates to CROSS APPLY.
If collection selector ends with DefaultIfEmpty then it is OUTER APPLY.

- Add support for Cross Apply
- Add Support for Outer Apply
- Convert Cross Apply to Inner Join when possible
- Convert Outer Apply to Left Join when possible
- Add translation for DefaultIfEmpty
- Add translation for both overloads of SelectMany
- Handle DefaultIfEmpty & SelectMany without collectionSelector in Navigation Expansion
- Ensure columns are in projection when generating join predicate from a correlated subquery

Currently there are no tests for Cross/Outer Apply.
Our earlier Cross Apply got converted to join. N+1 evaluation tests are disabled right now, which would generate Cross Apply.
We never supported Outer Apply in past.

Resolves #15711
Resolves #12567
Resolves #12572
Resolves #12872
Resolves #16330
Resolves #15081
Resolves #16989

Re-enable tests for #12449
@smitpatel
Copy link
Contributor Author

Renamed CrossApplyExpression -> InnerJoinLateralExpression & OuterApplyExpression -> LeftJoinLateralExpression to match with formal SQL terminology. Also updated relational implementation and moved SqlServer specific sql syntax in provider code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment