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

Cosmos: translate string Contains, StartsWith, and EndsWith #19563

Merged
merged 4 commits into from
Jan 11, 2020

Conversation

jviau
Copy link
Contributor

@jviau jviau commented Jan 10, 2020

Addresses part of #16143

This PR introduces translation for string.StartsWith, string.EndsWith, and string.Contains in cosmos queries. They are converted to the built-in cosmos functions STARTSWITH, ENDSWITH, and CONTAINS respectively.

Not sure if this contribution is wanted, but I had added this extension to my code as I was playing around with efcore cosmos and figured I would offer to contribute it back. If it is wanted, I will add tests and make changes as requested.

Summary of changes
- Adds initial StringMethodTranslator for Cosmos provider.
- Translates Contains, StartsWith, and EndsWith

Addresses part of dotnet#16143
Copy link
Member

@AndriySvyryd AndriySvyryd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are already tests for this in NorthwindFunctionsQueryCosmosTest, look for "String_Contains", "String_StartsWith", "String_EndsWith". Unskip them and correct the expected SQL.

- Remove infer type mapping from cosmos StringMethodTranslator
- Unskips and improves cosmos functional tests for startswith, endswith,
and contains
- Adds SqlFunctionExpression support to ApplyDefaultTypeMapping
@jviau
Copy link
Contributor Author

jviau commented Jan 11, 2020

@AndriySvyryd , I unskipped those tests and updated them. I also found that I could not have a null TypeMapping, as that would throw in the tests. I used the ApplyDefaultTypeMapping as you suggested (after adding support for SqlFunctionExpression to it).

@AndriySvyryd AndriySvyryd changed the title [WIP] Cosmos: translate string Contains, StartsWith, and EndsWith Cosmos: translate string Contains, StartsWith, and EndsWith Jan 11, 2020
private SqlExpression TranslateSystemFunction(string function, SqlExpression instance, SqlExpression pattern, Type returnType)
{
Check.NotNull(instance, nameof(instance));
return _sqlExpressionFactory.ApplyDefaultTypeMapping(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApplyDefaultTypeMapping shouldn't be required. If it does not apply default at later stage automatically then there is bug somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Can a different issue be opened for that? It may be a test validation issue - it is an error along the lines of "SqlExpression without TypeMapping found in query" and the test fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #19567

- Inline cosmos string method test variables
- Remove fact attributes, they are inherited
@AndriySvyryd AndriySvyryd merged commit 83dccdc into dotnet:master Jan 11, 2020
@jviau jviau deleted the cosmos-string-translator branch January 11, 2020 08:38
@AndriySvyryd
Copy link
Member

Thanks for your contribution!

svengeance pushed a commit to svengeance/EntityFrameworkCore that referenced this pull request Jan 15, 2020
…9563)

Summary of changes
- Adds initial StringMethodTranslator for Cosmos provider.
- Translates Contains, StartsWith, and EndsWith

Addresses part of dotnet#16143
@nickwilsonr
Copy link

So when can we expect this to be released to Nuget?

@AndriySvyryd
Copy link
Member

@nickwilsonr EF Core 5.0 is aligned with .NET 5.0 set to release in November

@nickwilsonr
Copy link

@nickwilsonr EF Core 5.0 is aligned with .NET 5.0 set to release in November

So this fix cant/wont be included in an upcoming 3.x release? 10 months is a VERY LONG time to wait for something that is pretty basic EF functionality.

@AndriySvyryd
Copy link
Member

@nickwilsonr Unfortunately there will be no 3.x releases apart from 3.0.x and 3.1.x

@nickwilsonr
Copy link

@AndriySvyryd, this seems like a pretty big problem.

What are we supposed to do here for the next 10 months? For small projects it may be okay to simply pull the entire collection into memory to do these string comparisons, but that's not going to scale. I'm looking for an enterprise-level solution here, which is kinda the whole point of Cosmos.

@AndriySvyryd
Copy link
Member

@nickwilsonr You can use daily builds. There are few changes to Cosmos for 5.0 so these should be pretty stable, the downside is that you might need to also upgrade other packages that have common dependencies.

@jviau
Copy link
Contributor Author

jviau commented Jan 21, 2020

@nickwilsonr, if you want to, you can also add this functionality yourself. It does use some internal API's though. I uploaded some sample code here for you: https://github.com/jviau/samples/tree/master/src/efcore. This supports more than what I included in this PR 😄 , but I haven't tested it all.

@ajcvickers
Copy link
Member

@nickwilsonr We will certainly pass on your feedback to those who handle release schedules. Beyond that we strive to keep a high quality in previews and daily builds so that people can use those builds while waiting for RTM releases. (3.0 was an exception to this due to the query overhaul.)

@nickwilsonr
Copy link

@jviau
Just gave your code a try, but I'm getting this exception when I try to run my query:
Null TypeMapping in Sql Tree

If I put a breakpoint in CosmosStringMethodCallTranslator on line 90, then arguments[0] (which is the RHS of the CONTAINS operation) does have a null TypeMapping, but I have no idea why or how to resolve this.

The query I'm using for testing is VERY simple:
context.Transactions.Where(t => t.Content.Contains("12345"))

For point of reference, Transactions is the DBSet for the Transaction model, which contains a string property called Content

@AndriySvyryd
Copy link
Member

@nickwilsonr Can you file this as a new issue?

@jviau
Copy link
Contributor Author

jviau commented Jan 30, 2020

I believe an issue for this is already open. I encountered it during this PR, but we assumed it was a test only issue. It is probably a validation issue then as cosmos provider does work fine when that value is set to even an incorrect value. So long as it's not null.

@AndriySvyryd
Copy link
Member

@jviau You mean #19567? That one is about addressing the root cause, but current code should use ApplyDefaultTypeMapping to avoid this exception.

@nickwilsonr I think you are referring to the code from https://github.com/jviau/samples/tree/master/src/efcore. If so file an issue on that repo.

@jviau
Copy link
Contributor Author

jviau commented Jan 30, 2020

Should be fixed in the sample now: jviau/samples#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants