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

Add extensibility point for IQueryOptimizer #444

Closed
wants to merge 1 commit into from

Conversation

austindrenski
Copy link
Contributor

@austindrenski austindrenski commented Jun 1, 2018

This work supports #431 by providing extensibility points for query rewriting expression visitors.

@austindrenski austindrenski force-pushed the add-extension-hooks branch from 0145d8c to e17c5ea Compare June 1, 2018 03:12
@austindrenski
Copy link
Contributor Author

@roji this is ready for review.

@roji
Copy link
Member

roji commented Jun 18, 2018

@austindrenski the general approach and goals look good. However, the two services you're replacing (IExpressionFragmentTranslator, IQueryOptimizer) are from an EF Core internal namespace, which is something we should be wary of doing.

How about submitting an issue/PR to EF Core itself, for moving these services out of Internal and providing the extensibility point? If you explain the Npgsql needs clearly I don't think they'll object to it. Many services were defined as Internal because they didn't want to commit to a stable interface for them early on, but it seems that things have matured enough for these to be nailed down.

Let me know what you think, and please cc me from any issue/PR.

@roji
Copy link
Member

roji commented Jun 18, 2018

However, before working on an EF Core issue/PR, it seems like we need to decide whether the null element discrepancy (described here) prevents us from translating constructs such as array1.All(x => array2.Contains(x)) altogether, in which case this PR would have no real use.

@austindrenski austindrenski self-assigned this Jun 24, 2018
@austindrenski austindrenski added enhancement New feature or request blocked labels Jun 24, 2018
@austindrenski austindrenski added this to the 2.2.0 milestone Jun 24, 2018
@austindrenski austindrenski force-pushed the add-extension-hooks branch 2 times, most recently from 06621e5 to 59778fb Compare July 21, 2018 21:38
@austindrenski austindrenski force-pushed the add-extension-hooks branch 2 times, most recently from 2bea785 to 7d484a7 Compare July 25, 2018 03:57
@austindrenski austindrenski changed the title Add extensibility points for fragments and visitors Add extensibility point for IQueryOptimizer Jul 25, 2018
Creates Npgsql implementations of `IExpressionFragmentTranslator`
and `IQueryOptimizer` to support more complex translations.

These classes make it easier to inject new fragment translations
and expression rewrites into the EF Core translation process.

This is split out from npgsql#431. Working examples can be found there.
@roji
Copy link
Member

roji commented Jul 31, 2018

@austindrenski is this still actually useful for anything?

@austindrenski
Copy link
Contributor Author

@roji Ehh.. It's on the 3.0 milestone for EF Core, but that's a long ways off still. I'll close this, and reopen in the future if the upstream changes are made.

@roji
Copy link
Member

roji commented Jul 31, 2018

@austindrenski to be clear, I'm actually not 100% against us overriding internal EF Core types - I've done this several times in the past (not sure if there are any currently). The only consequence is having to be reactive to EF Core minor version releases, since breakage may be introduced to these types. But as a general rule we've always released in lock-step with EF Core anyway, so it's not a big deal.

The question is whether there's any value in this, in light of the null behavior discrepancy of array1.All(x => array2.Contains(x)). If there's real value I'm fine with providing our own implementation of IQueryOptimizer, otherwise we can forget about it...

@austindrenski
Copy link
Contributor Author

The question is whether there's any value in this, in light of the null behavior discrepancy of array1.All(x => array2.Contains(x)). If there's real value I'm fine with providing our own implementation of IQueryOptimizer, otherwise we can forget about it...

So right now, I don't think it adds any value...

As for the null discrepancy, I went ahead and dropped the translation of array1.All(x => array2.Contains(x)) in favor of EF.Functions.Contains(array1, array2).

I think it would still be cool to translate the former if the discrepancy could be handled through the UseRelationalNulls style offsetting. But, I haven't had time to look into whether the array operators could be offset in the same way.

The only consequence is having to be reactive to EF Core minor version releases, since breakage may be introduced to these types. But as a general rule we've always released in lock-step with EF Core anyway, so it's not a big deal.

As mentioned in #541, there are some functions for which translation will involve sub-query manipulation. (The added complexity is why I'm splitting them into another PR.)

I've got a feeling that IQueryOptimizer might tame some of that complexity, but I'm okay waiting to introduce an implementation until I've had some time to look specifically at unnest and array_agg.

Since there could be a cost to introducing it (e.g. minor version breakages), we might as well wait until there's a well-defined use case for it.

@roji
Copy link
Member

roji commented Aug 1, 2018

Makes sense, thanks!

@austindrenski austindrenski deleted the add-extension-hooks branch September 29, 2018 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants