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 quantile() argument not being passed through #2780

Merged
merged 11 commits into from
Oct 26, 2020

Conversation

vpranckaitis
Copy link
Collaborator

What this PR does / why we need it:

Fix quantile() argument not being passed through when processing promql expression. This improves m3query compatibility

Special notes for your reviewer:

Does this PR introduce a user-facing and/or backwards incompatible change?:

NONE

Does this PR require updating code package or user-facing documentation?:

NONE

@CLAassistant
Copy link

CLAassistant commented Oct 21, 2020

CLA assistant check
All committers have signed the CLA.

@vpranckaitis vpranckaitis changed the title [query] Fix quantile argument not being passed through [query] Fix quantile() argument not being passed through Oct 21, 2020
@codecov
Copy link

codecov bot commented Oct 21, 2020

Codecov Report

Merging #2780 into master will decrease coverage by 0.9%.
The diff coverage is 0.0%.

Impacted file tree graph

@@           Coverage Diff            @@
##           master   #2780     +/-   ##
========================================
- Coverage    61.5%   60.6%   -1.0%     
========================================
  Files        1015    1015             
  Lines       92824   92920     +96     
========================================
- Hits        57106   56315    -791     
- Misses      31220   32184    +964     
+ Partials     4498    4421     -77     
Flag Coverage Δ
#aggregator 62.7% <ø> (-1.6%) ⬇️
#cluster 77.6% <ø> (ø)
#collector 64.3% <ø> (ø)
#dbnode 63.7% <ø> (+<0.1%) ⬆️
#m3em 48.8% <ø> (-18.8%) ⬇️
#m3ninx 60.9% <ø> (-8.6%) ⬇️
#m3nsch 51.1% <ø> (ø)
#msg 70.6% <ø> (+0.1%) ⬆️
#query 48.7% <0.0%> (-0.1%) ⬇️
#x 63.0% <ø> (-1.1%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.


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 4cca152...c5b23bb. Read the comment docs.

@vpranckaitis vpranckaitis requested a review from linasm October 21, 2020 13:31
src/query/parser/promql/matchers.go Show resolved Hide resolved
@@ -90,27 +90,31 @@ func NewAggregationOperator(expr *promql.AggregateExpr) (parser.Params, error) {
Without: expr.Without,
}

op := getAggOpType(opType)
if op == common.UnknownOpType {
switch op := getAggOpType(opType); op {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: this switch has multi-line case blocks, would be a bit easier on the eyes if they were separated with empty lines.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines 110 to 112
"quantile(0, quack)",
"quantile(0.8, avg_over_time(quack[30s]))",
"quantile(1, avg(avg_over_time(quack[30s])) by (name))"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Better use multi_10 metrics, it will give you 10 series.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines 108 to 109
"queryGroup":"quantile",
"queries":[
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mini nit:

Suggested change
"queryGroup":"quantile",
"queries":[
"queryGroup": "quantile",
"queries": [

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

"quantile(0.8, avg_over_time(quack[30s]))",
"quantile(1, avg(avg_over_time(quack[30s])) by (name))"
],
"steps" : [
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mini nit:

Suggested change
"steps" : [
"steps": [

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@@ -90,27 +90,35 @@ func NewAggregationOperator(expr *promql.AggregateExpr) (parser.Params, error) {
Without: expr.Without,
}

op := getAggOpType(opType)
if op == common.UnknownOpType {
switch op := getAggOpType(opType); op {
Copy link
Collaborator

@arnikola arnikola Oct 22, 2020

Choose a reason for hiding this comment

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

nit: switch getAggOpType(opType) { is a simpler way of doing this

Suggested change
switch op := getAggOpType(opType); op {
switch getAggOpType(opType) {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines 111 to 121
val, err := resolveScalarArgument(expr.Param)
if err != nil {
return nil, err
}

nodeInformation.Parameter = val
return aggregation.NewAggregationOp(op, nodeInformation)

default:
return aggregation.NewAggregationOp(op, nodeInformation)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit; Don't think you need the default case or the special return here if you move the aggregation.NewAggregationOp(op, nodeInformation) out of the switch

Copy link
Collaborator Author

Choose a reason for hiding this comment

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


# Bug #5276.
# FAILING issue #56. scalar() inside aggregate function arguments kills the server
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is meant by killing the server? Did this change make the failure in this case worse than it was before?

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 seems that quantile(scalar(foo), ...) eventually becomes quantile(NaN, ...), which causes panic in following computations. I've added a check if q == NaN and a unit test, also updated the comment 9815297

panic: runtime error: index out of range [-9223372036854775808]
goroutine 13088 [running]:
github.com/m3db/m3/src/query/functions/aggregation.quantileFn(0x7ff8000000000001, 0xc007d7e370, 0xa, 0xa, 0xc00d2a11a0)
go/src/github.com/m3db/m3/src/query/functions/aggregation/quantile.go:86 +0x1d5
github.com/m3db/m3/src/query/functions/aggregation.bucketedQuantileFn(0x7ff8000000000001, 0xc007d7e050, 0xa, 0xa, 0xc0005d8380, 0xa, 0x10, 0xa)
go/src/github.com/m3db/m3/src/query/functions/aggregation/quantile.go:67 +0x17a
github.com/m3db/m3/src/query/functions/aggregation.makeQuantileFn.func1(0xc007d7e050, 0xa, 0xa, 0xc0005d8380, 0xa, 0x10, 0x0)
go/src/github.com/m3db/m3/src/query/functions/aggregation/quantile.go:42 +0x68
github.com/m3db/m3/src/query/functions/aggregation.(*baseNode).ProcessBlock(0xc00dbbb8c0, 0xc0060bdef0, 0x298a4f0, 0x1, 0x1ce15e0, 0xc00a19a600, 0x1, 0x1cf2680, 0x2a210e0, 0x1cd1540)
go/src/github.com/m3db/m3/src/query/functions/aggregation/base.go:163 +0x480
<...>

return nil, err
}

nodeInformation.Parameter = val
Copy link
Collaborator

Choose a reason for hiding this comment

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

May be worth adding a test for this; may be a bit complex though since it would need to generate the op, get the node, then create a mock block and run it against functions (since we can't really inspect this otherwise; maybe add a NodeInformation() on parser.Params? Although that may lead to a deeper rabbithole)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We've discussed this with @linasm and reached a similar conclusion about it being not very straightforward. For now, the tests in aggregators.test and queries.json should provide some coverage. I may look into this further in a follow-up PR.

Copy link
Collaborator

@arnikola arnikola left a comment

Choose a reason for hiding this comment

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

Approved /w nits

@arnikola arnikola removed their assignment Oct 22, 2020
Copy link
Collaborator

@linasm linasm left a comment

Choose a reason for hiding this comment

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

Well done overall, had a few minor suggestions.

@@ -48,6 +48,10 @@ func bucketedQuantileFn(q float64, values []float64, bucket []int) float64 {
return math.NaN()
}

if math.IsNaN(q) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Merge it with the if above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

expected := math.NaN()
actual := bucketedQuantileFn(math.NaN(), values, buckets)

test.EqualsWithNans(t, expected, actual)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just make it a more direct require.True(t, math.IsNaN(actual))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

buckets := []int{0, 1}

expected := math.NaN()
actual := bucketedQuantileFn(math.NaN(), values, buckets)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also please cover the cases with empty values and empty buckets (if they are not currently covered).
Can do it in the same test function, especially if you inline those arguments a bit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@@ -117,6 +117,18 @@ func TestQuantileFnSingleNonNan(t *testing.T) {
test.EqualsWithNansWithDelta(t, expected, actual, math.Pow10(-5))
}

func TestQuantileNanAndEmptyArguments(t *testing.T) {
actual := []float64{
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a good idea, but it will not report which case(s) fail.
There is a more standard approach for such tests in go, called 'test tables`, eg.:

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

@linasm linasm left a comment

Choose a reason for hiding this comment

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

LGTM

@vpranckaitis
Copy link
Collaborator Author

@arnikola since I made quite a few changes while addressing the comments, I'm re-adding you for review

@vpranckaitis vpranckaitis requested a review from arnikola October 23, 2020 11:10
@arnikola arnikola removed their assignment Oct 26, 2020
Copy link
Collaborator

@arnikola arnikola left a comment

Choose a reason for hiding this comment

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

lgtm

@vpranckaitis vpranckaitis merged commit d47dcc3 into master Oct 26, 2020
@vpranckaitis vpranckaitis deleted the vilius/pass_quantile_argument branch October 26, 2020 12:21
soundvibe added a commit that referenced this pull request Oct 29, 2020
* master:
  Support dynamic namespace resolution for embedded coordinators (#2815)
  [dbnode] Add index regexp DFA compilation cache to avoid allocating DFAs for same expressions (#2814)
  [dbnode] Set default cache on retrieve to false, prepare testing with cache none (#2813)
  [tools] Output annotations as base64 (#2743)
  Add Reset Transformation (#2794)
  [large-tiles] Fix for a reverse index when querying downsampled namespace (#2808)
  [dbnode] Evict info files cache before index bootstrap in peers bootstrapper (#2802)
  [dbnode] Bump default filesystem persist rate limit (#2806)
  [coordinator] Add metrics and configurability of downsample and ingest writer worker pool (#2797)
  [dbnode] Fix concurrency granularity of seekerManager.UpdateOpenLease (#2790)
  [dbnode] Use correct import path for atomic library (#2801)
  Regenerate carbon automapping rules on namespaces changes (#2793)
  Enforce matching retention and index block size (#2783)
  [query] Add ClusterNamespacesWatcher and use to generate downsample automapper rules (#2782)
  [query][dbnode] Wire up etcd-backed Clusters implementation in coordinator (#2758)
  [query] Fix quantile() argument not being passed through (#2780)

# Conflicts:
#	src/query/parser/promql/matchers.go
soundvibe added a commit that referenced this pull request Oct 29, 2020
* master:
  [query] Improve precision for variance and stddev of equal values (#2799)
  Support dynamic namespace resolution for embedded coordinators (#2815)
  [dbnode] Add index regexp DFA compilation cache to avoid allocating DFAs for same expressions (#2814)
  [dbnode] Set default cache on retrieve to false, prepare testing with cache none (#2813)
  [tools] Output annotations as base64 (#2743)
  Add Reset Transformation (#2794)
  [large-tiles] Fix for a reverse index when querying downsampled namespace (#2808)
  [dbnode] Evict info files cache before index bootstrap in peers bootstrapper (#2802)
  [dbnode] Bump default filesystem persist rate limit (#2806)
  [coordinator] Add metrics and configurability of downsample and ingest writer worker pool (#2797)
  [dbnode] Fix concurrency granularity of seekerManager.UpdateOpenLease (#2790)
  [dbnode] Use correct import path for atomic library (#2801)
  Regenerate carbon automapping rules on namespaces changes (#2793)
  Enforce matching retention and index block size (#2783)
  [query] Add ClusterNamespacesWatcher and use to generate downsample automapper rules (#2782)
  [query][dbnode] Wire up etcd-backed Clusters implementation in coordinator (#2758)
  [query] Fix quantile() argument not being passed through (#2780)
  [query] Add "median" aggregation to Graphite aggregate() function (#2774)
  [r2] Ensure KeepOriginal is propagated when adding/reviving rules (#2796)
  [dbnode] Update default db read limits  (#2784)
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.

4 participants