-
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
Fix to #28648 - Json/Query: translate element access of a json array #29656
Conversation
517e7c7
to
f0daace
Compare
src/EFCore.Relational/Query/Internal/CollectionIndexerToElementAtConvertingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
Outdated
Show resolved
Hide resolved
...l/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs
Show resolved
Hide resolved
a67d570
to
f852a75
Compare
...EFCore.Relational/Query/Internal/CollectionIndexerToElementAtNormalizingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
f852a75
to
3f1b691
Compare
new version up @roji |
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.
LGTM, lots of comments but almost all nits. Would prefer we didn't exempt byte[] from the ElementAt normalization though...
...EFCore.Relational/Query/Internal/CollectionIndexerToElementAtNormalizingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
...EFCore.Relational/Query/Internal/CollectionIndexerToElementAtNormalizingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
var subquery = mcne.Subquery; | ||
|
||
if (subquery is MethodCallExpression selectMethodCall | ||
&& selectMethodCall.Method.IsGenericMethod |
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.
Can integrate into pattern above (also block below)
// MCNE(JSON_QUERY($[0].Collection)) | ||
// MCNE(JSON_QUERY($[0].Collection).AsQueryable()) | ||
// MCNE(JSON_QUERY($[0].Collection).Select(xx => xx.Includes()) | ||
// MCNE(JSON_QUERY($[0].Collection).AsQueryable().Select(xx => xx.Includes()) |
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.
Can we also have AsQueryable after the Select? If so that's not handled below (can just do a while loop to unwrap until nothing is left).
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 don't produce those kinds of expressions - we add asqueryable when the collection is List or other Enumerable. So its always either AsQueryable().Select() or just Select(). Of course customers could also write queries like that (but why?)
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.
OK, thanks for clarifying, no problem.
3999868
to
8f76e65
Compare
new version up @roji |
Converting indexer over list/array into ElementAt, so that nav expansion understands it and can perform pushown and inject MaterializeCollectionNavigation expression where necessary. In translation phase (specifically in ExpandSharedTypeEntities) we recognize the pattern that nav expansion creates and if the root is JsonQueryExpression, we apply collection index over it. JsonQueryExpression path segment now consists of two components - string representing JSON property name and SqlExpression representing collection index (it can be constant, parameter or any arbitrary expression that resolves to int) Deduplication is heavily restricted currently - we only de-duplicate projections whose additional path consists of JSON property accesses only (no collection indexes allowed). All queries projecting entities that need JSON array access must be set to NoTracking (for now). This is because we don't flow those collection index values into shaper. Instead, the ordinal keys are filled with dummy values, which prohibits us from doing proper change tracking. Fixes #28648
8f76e65
to
94be38c
Compare
Converting indexer over list/array into ElementAt, so that nav expansion understands it and can perform pushown and inject MaterializeCollectionNavigation expression where necessary. In translation phase we recognize the pattern that nav expansion creates and if the root is JsonQueryExpression, we apply collection index over it. JsonQueryExpression path segment now consists of two components - string representing JSON property name and SqlExpression representing collection index (it can be constant, parameter or any arbitrary expression that resolves to int)
Deduplication is heavily restricted currently - we only de-duplicate projections whose additional path consists of JSON property accesses only (no collection indexes allowed). All queries projecting entities that need JSON array access must be set to NoTracking (for now). This is because we don't flow those collection index values into shaper. Instead, the ordinal keys are filled with dummy values, which prohibits us from doing proper change tracking.
Fixes #28648