mirror of https://github.com/prometheus/prometheus
Merge pull request #9248 from LeviHarrison/atan2-binary-op
PromQL: Add `atan2` binary operatorpull/9347/head
commit
f103acd513
|
@ -40,6 +40,16 @@ grouping labels becoming the output label set. The metric name is dropped. Entri
|
|||
for which no matching entry in the right-hand vector can be found are not part of
|
||||
the result.
|
||||
|
||||
### Trigonometric binary operators
|
||||
|
||||
The following trigonometric binary operators, which work in radians, exist in Prometheus:
|
||||
|
||||
* `atan2` (based on https://pkg.go.dev/math#Atan2)
|
||||
|
||||
Trigonometric operators allow trigonometric functions to be executed on two vectors using
|
||||
vector matching, which isn't available with normal functions. They act in the same manner
|
||||
as arithmetic operators.
|
||||
|
||||
### Comparison binary operators
|
||||
|
||||
The following binary comparison operators exist in Prometheus:
|
||||
|
@ -264,7 +274,7 @@ The following list shows the precedence of binary operators in Prometheus, from
|
|||
highest to lowest.
|
||||
|
||||
1. `^`
|
||||
2. `*`, `/`, `%`
|
||||
2. `*`, `/`, `%`, `atan2`
|
||||
3. `+`, `-`
|
||||
4. `==`, `!=`, `<=`, `<`, `>=`, `>`
|
||||
5. `and`, `unless`
|
||||
|
|
|
@ -2116,6 +2116,8 @@ func vectorElemBinop(op parser.ItemType, lhs, rhs float64) (float64, bool) {
|
|||
return lhs, lhs >= rhs
|
||||
case parser.LTE:
|
||||
return lhs, lhs <= rhs
|
||||
case parser.ATAN2:
|
||||
return math.Atan2(lhs, rhs), true
|
||||
}
|
||||
panic(errors.Errorf("operator %q not allowed for operations between Vectors", op))
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ NEQ_REGEX
|
|||
POW
|
||||
SUB
|
||||
AT
|
||||
ATAN2
|
||||
%token operatorsEnd
|
||||
|
||||
// Aggregators.
|
||||
|
@ -156,7 +157,7 @@ START_METRIC_SELECTOR
|
|||
%left LAND LUNLESS
|
||||
%left EQLC GTE GTR LSS LTE NEQ
|
||||
%left ADD SUB
|
||||
%left MUL DIV MOD
|
||||
%left MUL DIV MOD ATAN2
|
||||
%right POW
|
||||
|
||||
// Offset modifiers do not have associativity.
|
||||
|
@ -237,6 +238,7 @@ aggregate_modifier:
|
|||
|
||||
// Operator precedence only works if each of those is listed separately.
|
||||
binary_expr : expr ADD bin_modifier expr { $$ = yylex.(*parser).newBinaryExpression($1, $2, $3, $4) }
|
||||
| expr ATAN2 bin_modifier expr { $$ = yylex.(*parser).newBinaryExpression($1, $2, $3, $4) }
|
||||
| expr DIV bin_modifier expr { $$ = yylex.(*parser).newBinaryExpression($1, $2, $3, $4) }
|
||||
| expr EQLC bin_modifier expr { $$ = yylex.(*parser).newBinaryExpression($1, $2, $3, $4) }
|
||||
| expr GTE bin_modifier expr { $$ = yylex.(*parser).newBinaryExpression($1, $2, $3, $4) }
|
||||
|
@ -674,7 +676,7 @@ series_value : IDENTIFIER
|
|||
aggregate_op : AVG | BOTTOMK | COUNT | COUNT_VALUES | GROUP | MAX | MIN | QUANTILE | STDDEV | STDVAR | SUM | TOPK ;
|
||||
|
||||
// inside of grouping options label names can be recognized as keywords by the lexer. This is a list of keywords that could also be a label name.
|
||||
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK | START | END;
|
||||
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK | START | END | ATAN2;
|
||||
|
||||
unary_op : ADD | SUB;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -97,6 +97,7 @@ var key = map[string]ItemType{
|
|||
"and": LAND,
|
||||
"or": LOR,
|
||||
"unless": LUNLESS,
|
||||
"atan2": ATAN2,
|
||||
|
||||
// Aggregators.
|
||||
"sum": SUM,
|
||||
|
|
|
@ -340,6 +340,10 @@ var tests = []struct {
|
|||
input: "bool",
|
||||
expected: []Item{{BOOL, 0, "bool"}},
|
||||
},
|
||||
{
|
||||
input: "atan2",
|
||||
expected: []Item{{ATAN2, 0, "atan2"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -467,3 +467,17 @@ eval instant at 5m test_total < bool test_smaller
|
|||
{instance="localhost"} 0
|
||||
|
||||
eval instant at 5m test_total < test_smaller
|
||||
|
||||
clear
|
||||
|
||||
# Testing atan2.
|
||||
load 5m
|
||||
trigy{} 10
|
||||
trigx{} 20
|
||||
trigNaN{} NaN
|
||||
|
||||
eval instant at 5m trigy atan2 trigx
|
||||
trigy{} 0.4636476090008061
|
||||
|
||||
eval instant at 5m trigy atan2 trigNaN
|
||||
trigy{} NaN
|
||||
|
|
|
@ -28,6 +28,7 @@ export const binOpTerms = [
|
|||
{ label: '<' },
|
||||
{ label: '<=' },
|
||||
{ label: '!=' },
|
||||
{ label: 'atan2' },
|
||||
{ label: 'and' },
|
||||
{ label: 'or' },
|
||||
{ label: 'unless' },
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
@precedence {
|
||||
pow @right,
|
||||
mul @left,
|
||||
mul @left
|
||||
add @left,
|
||||
eql @left,
|
||||
and @left,
|
||||
|
@ -69,6 +69,7 @@ BinaryExpr {
|
|||
Expr !mul Mul BinModifiers Expr |
|
||||
Expr !mul Div BinModifiers Expr |
|
||||
Expr !mul Mod BinModifiers Expr |
|
||||
Expr !mul Atan2 BinModifiers Expr |
|
||||
Expr !add Add BinModifiers Expr |
|
||||
Expr !add Sub BinModifiers Expr |
|
||||
Expr !eql Eql BinModifiers Expr |
|
||||
|
@ -333,6 +334,7 @@ NumberLiteral {
|
|||
// Contextual keywords
|
||||
|
||||
@external extend {Identifier} extendIdentifier from "./tokens" {
|
||||
Atan2,
|
||||
Avg,
|
||||
Bottomk,
|
||||
Count,
|
||||
|
|
|
@ -840,3 +840,10 @@ sum:my_metric_name:rate5m
|
|||
|
||||
==>
|
||||
MetricName(MetricIdentifier(Identifier))
|
||||
|
||||
# Testing Atan2 inherited precedence level
|
||||
|
||||
1 + foo atan2 bar
|
||||
|
||||
==>
|
||||
PromQL(Expr(BinaryExpr(Expr(NumberLiteral),Add,BinModifiers,Expr(BinaryExpr(Expr(VectorSelector(MetricIdentifier(Identifier))),Atan2,BinModifiers,Expr(VectorSelector(MetricIdentifier(Identifier))))))))
|
|
@ -14,6 +14,7 @@
|
|||
import {
|
||||
And,
|
||||
Avg,
|
||||
Atan2,
|
||||
Bool,
|
||||
Bottomk,
|
||||
By,
|
||||
|
@ -58,6 +59,7 @@ export const specializeIdentifier = (value, stack) => {
|
|||
|
||||
const contextualKeywordTokens = {
|
||||
avg: Avg,
|
||||
atan2: Atan2,
|
||||
bottomk: Bottomk,
|
||||
count: Count,
|
||||
count_values: CountValues,
|
||||
|
|
|
@ -40,7 +40,7 @@ export function promQLLanguage(top: LanguageType): LRLanguage {
|
|||
'Avg Bottomk Count Count_values Group Max Min Quantile Stddev Stdvar Sum Topk': tags.operatorKeyword,
|
||||
'By Without Bool On Ignoring GroupLeft GroupRight Offset Start End': tags.modifier,
|
||||
'And Unless Or': tags.logicOperator,
|
||||
'Sub Add Mul Mod Div Eql Neq Lte Lss Gte Gtr EqlRegex EqlSingle NeqRegex Pow At': tags.operator,
|
||||
'Sub Add Mul Mod Div Atan2 Eql Neq Lte Lss Gte Gtr EqlRegex EqlSingle NeqRegex Pow At': tags.operator,
|
||||
UnaryOp: tags.arithmeticOperator,
|
||||
'( )': tags.paren,
|
||||
'[ ]': tags.squareBracket,
|
||||
|
|
Loading…
Reference in New Issue