-
-
Notifications
You must be signed in to change notification settings - Fork 158
QueryExpression rewriter #820
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
QueryExpression rewriter #820
Conversation
namespace JsonApiDotNetCore.Queries.Expressions | ||
{ | ||
/// <summary> | ||
/// Building block for rewriting <see cref="QueryExpression" /> trees. It walks nested expressions and updates parent on changes. |
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.
It walks through nested expressions?
I am a little confused: I don't see any nested traversing happening in this class. Do you mean it is a building block for such traversal which is performed by some encapsulating object?
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.
The visitor pattern is recursive by nature (through double-dispatch). For example, for an expression like and(not(or(...equals...)))
you'd override VisitComparison and rewrite the equals
subterm, passing in the source text.
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.
I'm not sure if to walk nested expressions is grammatically correct, or if it should be to walk through nested expressions
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.
I'm still confused with the use of the word recursion here, because there is no code calling itself which is usually what recursion means in practise. ("Recursion solves such recursive problems by using functions that call themselves from within their own code.")
Or would the VisitComparison
override be calling itself in your example?
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.
If you don't understand, familiarize yourself with the visitor pattern I linked to. Recursion does not mean a recursive function here.
I'll add 'through'
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.
While the rewriter could be implemented outside of this repository, it being correct highly depends on:
I am also not sure if I fully understand your motivation for including this class in the repository rather than having it in our private repo
- Proper Equals implementation on all terminal nodes (so we update them when properties are added)
I understand that the rewriter requires proper Equals
implementation. This PR introduces this, which is a valuable contribution by itself, even if a rewriter would live in another repository. Since this component isn't used or referenced anywhere in this repository, I wonder if it would make sense to include it here rather than in our own? Or conversely: can we work out a solid use-case for a dev, include it in the docs and have more reasons to have it in this repo?
src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs
Outdated
Show resolved
Hide resolved
…re nested `return null`s, so I rewrote them for single entry/exit.
This PR adds a building block for rewriting a
QueryExpression
tree by recursively walking it and propagating changes up to the root of the tree. To minimize memory pressure, existing subtrees are reused where possible.Aside from emitting a new tree, the rewriter can also be used to just recursively walk the tree, for example if you want to add extra validations on subterms.
While the rewriter could be implemented outside of this repository, it being correct highly depends on:
QueryExpression
sIt is much more likely these are kept in sync within this repository, compared to spreading it out, then breaking subtly on version upgrades.