-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
support "pipe" function chaining syntax #2042
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2042 +/- ##
==========================================
+ Coverage 69.69% 69.72% +0.03%
==========================================
Files 78 78
Lines 7440 7448 +8
Branches 1440 1442 +2
==========================================
+ Hits 5185 5193 +8
Misses 1969 1969
Partials 286 286
Continue to review full report at Codecov.
|
Obviously this needs docs before it would be merge-able, I'd also like to write some tests for both the parser and evaluator since coverage is pretty weak there right now. Feedback would be appreciated before I go ahead with that though. |
That would certainly make it more readable. |
@@ -14,7 +14,7 @@ def evaluateTarget(requestContext, target): | |||
return result | |||
|
|||
|
|||
def evaluateTokens(requestContext, tokens, replacements=None): | |||
def evaluateTokens(requestContext, tokens, replacements=None, pipedArg=None): |
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.
Could you please elaborate how pipedArg is passed here?
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.
pipedArg
is passed when evaluating the rightmost piped function, the value passed in will be the parse tree for the remaining part of the expression. You can see on line 30 & 31 that the rightMost
piped call is pop()
ed off the stack and tokens
is then passed as pipedArg
when it's evaluated. This mechanism is how the piped calls are "converted" back to a regular nested set of function calls.
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.
Ah, missed that, sorry. Thanks!
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.
No worries, it's definitely the most non-obvious part of the change. I'll add some comments to explain what's going on there.
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.
Comments added
But in general, I'm very 👍 👍 👍 about that change, very nice addition to function syntax. |
This PR adds support for chaining functions together by "piping" the output of each function into the next (as the first parameter), much like the way they're presented in the Grafana UI.
When dealing with deeply-nested queries this keeps the arguments for each function together, and can help increase readability vs the current "nested" syntax.
With this update the following query:
can be written as:
or:
Piping is supported within function arguments, so the same expression could also be written as
A more useful example would be selecting series for the
total
parameter ofasPercent
:The syntax is unwrapped in the parser and evaluator, so there is no difference in how the actual render functions are called, the evaluator walks through the piped calls from right to left, passing the chain up to that point into the function as the first parameter.
The one change I had to make that would affect existing syntax is that the pipe character
|
is added to the list of symbols that aren't allowed in pathExpressions, but I doubt that's widely used since it would make working with the whisper files painful. If a user does have series with a pipe in the name they can still be selected but the pipe would need to be escaped with a backslash.