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

[query] Fix variadic functions #1846

Merged
merged 5 commits into from
Aug 2, 2019
Merged

Conversation

arnikola
Copy link
Collaborator

Fixes #1844

Special notes for your reviewer: bit of scope creep; this PR also fixes a couple of incorrect functions, and lazifies some others.

@@ -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.
Copy link
Collaborator

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?

Copy link
Collaborator Author

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

Copy link
Collaborator Author

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"

Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Join the imports?

Copy link
Collaborator Author

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 {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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)

processorFn: makeRoundProcessor(spec),
}, nil

return 1, nil
Copy link
Collaborator

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?

Copy link
Collaborator Author

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 👍

}

if argCount != exprCount {
numVals--
Copy link
Collaborator

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 {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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

@@ -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 {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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
Copy link

codecov bot commented Aug 1, 2019

Codecov Report

Merging #1846 into master will increase coverage by <.1%.
The diff coverage is 74.4%.

Impacted file tree graph

@@           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
Flag Coverage Δ
#aggregator 82.4% <ø> (ø) ⬆️
#cluster 85.5% <ø> (ø) ⬆️
#collector 63.7% <ø> (ø) ⬆️
#dbnode 79.8% <ø> (ø) ⬆️
#m3em 73.2% <ø> (ø) ⬆️
#m3ninx 74.2% <ø> (ø) ⬆️
#m3nsch 51.1% <ø> (ø) ⬆️
#metrics 17.5% <ø> (ø) ⬆️
#msg 74.9% <ø> (+0.1%) ⬆️
#query 68.1% <74.4%> (+0.3%) ⬆️
#x 85.4% <ø> (-0.1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ffd32d...6b2d411. Read the comment docs.

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`.
Copy link
Collaborator

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()
Copy link
Collaborator

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).

Copy link
Collaborator Author

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

// 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
Copy link
Collaborator

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
)

Copy link
Collaborator

@robskillington robskillington left a 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

@arnikola arnikola merged commit ba60c45 into master Aug 2, 2019
@arnikola arnikola deleted the arnikola/variadic-functions branch August 2, 2019 18:46
schallert added a commit that referenced this pull request Aug 2, 2019
Got updated in #1745 but reverted in #1846.
schallert added a commit that referenced this pull request Aug 2, 2019
Got updated in #1745 but reverted in #1846.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Panic when parsing args for PromQL query
2 participants