-
Notifications
You must be signed in to change notification settings - Fork 455
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
[query] Fix variadic functions #1846
Conversation
@@ -26,6 +26,8 @@ import ( | |||
"github.com/m3db/m3/src/query/executor/transform" | |||
) | |||
|
|||
// FIXME: This is incorrect functionality. | |||
//' This should be an aggregation function that works in a step-wise fashion. |
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 create an issue for this?
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.
Sure; actually did the impl for this during the PR but didn't want to pollute this with unrelated stuff even further haha; maybe I'll just jam it in here too, it's actually tiny
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 damn actually a bit trickier than what I had since it's not quite a "standard" aggregation (i.e. it creates its own series if one hasn't been passed in); will add an issue for now
"github.com/m3db/m3/src/query/executor/transform" | ||
"github.com/m3db/m3/src/query/block" | ||
"github.com/m3db/m3/src/query/functions/lazy" | ||
|
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.
nit: Join the imports?
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.
Good call; weird that the linter didn't break the build on this though
func NewDateOp(optype string) (BaseOp, error) { | ||
if _, ok := datetimeFuncs[optype]; !ok { | ||
return emptyOp, fmt.Errorf("unknown date type: %s", optype) | ||
func buildTransform(args []interface{}, fn timeFn) block.ValueTransform { |
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.
Hm is args used in this method at all? Seems like only checked if length == 0?
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.
Yeah that's pretty much it; the way this family of functions work is that you can call them with 0 or 1 args, but either way it doesn't actually care about the value of the arg, just that it's there. I'll refactor this a bit to make it a bit nicer and clearer though (this will also address your comment re: n.Func.Name != linear.RoundType
)
src/query/functions/linear/round.go
Outdated
processorFn: makeRoundProcessor(spec), | ||
}, nil | ||
|
||
return 1, nil |
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.
Interesting, why does args > 1 always return a 1 value? Should this be error instead or no?
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.
So if there's more than 1 arg it will error out, 1 arg will attempt to parse the float, and this path is for 0 args which just returns the default value; will add a comment explaining this 👍
src/query/parser/promql/parse.go
Outdated
} | ||
|
||
if argCount != exprCount { | ||
numVals-- |
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.
Maybe we should call this numExpVals
or something to reflect it's what we're expecting?
"function %q, received %d", exprCount, n.Func.Name, argCount) | ||
} | ||
|
||
if argCount != exprCount { |
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.
For readability, does it make sense to do something like if argCount-1 == exprCount { ... }
do this logic?
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.
Sorry, don't quite get what you mean here
src/query/parser/promql/parse.go
Outdated
@@ -246,6 +273,10 @@ func (p *parseState) walk(node pql.Node) error { | |||
} else { | |||
if e, ok := expr.(*pql.MatrixSelector); ok { | |||
argValues = append(argValues, e.Range) | |||
} else if _, ok := expr.(*pql.VectorSelector); ok { | |||
if variadic != 0 && n.Func.Name != linear.RoundType { |
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.
Hm weird, what's special about not being round type?
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's actually more like we should only add it for date functions (which can have an arg that we don't actually care about), and it's using knowledge of prom internals (the functions with Variadic == 1
are the date ones and the round type) which is probably a little naughty haha
Will refactor slightly to make this clear and less janky
Codecov Report
@@ Coverage Diff @@
## master #1846 +/- ##
========================================
+ Coverage 72.2% 72.3% +<.1%
========================================
Files 987 986 -1
Lines 83822 83545 -277
========================================
- Hits 60556 60411 -145
+ Misses 19237 19127 -110
+ Partials 4029 4007 -22
Continue to review full report at Codecov.
|
if len(args) > 1 { | ||
return emptyOp, fmt.Errorf("invalid number of args for round: %d", len(args)) | ||
func parseArgs(args []interface{}) (float64, error) { | ||
// NB: if no args passed; this should use default value of `1`. |
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.
Nice, this definitely reads more clearer, good stuff.
q := `label_join(up, "foo", ",")` | ||
p, err := Parse(q, models.NewTagOptions()) | ||
require.NoError(t, err) | ||
_, _, _ = p.DAG() |
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.
nit: You could do assert.NotPanics(t, func() { _, _, _ = p.DAG() })
to be explicit about intent of calling this method (slighty nicer output if it does actually panic too, keeps running rest of the tests in the module rather than stopping whole test run).
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.
Oh that's pretty cool, makes sense it's an inbuilt
src/query/parser/promql/types.go
Outdated
// NewFunctionExpr creates a new function expr based on the type. | ||
func NewFunctionExpr( | ||
name string, | ||
argValues []interface{}, | ||
stringValues []string, | ||
hasArgValue bool, | ||
tagOptions models.TagOptions, | ||
) (parser.Params, bool, error) { | ||
var p parser.Params | ||
var err error |
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.
nit: Combine this into single var block?
var (
p parser.Params
err error
)
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 other than nits
Fixes #1844
Special notes for your reviewer: bit of scope creep; this PR also fixes a couple of incorrect functions, and lazifies some others.