mirror of
https://github.com/prometheus/prometheus.git
synced 2025-12-07 18:41:22 +01:00
WIP fill() operator
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
61f64a4cb1
commit
fcd8db67c1
@ -2824,7 +2824,8 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
||||
if matching.Card == parser.CardManyToMany {
|
||||
panic("many-to-many only allowed for set operators")
|
||||
}
|
||||
if len(lhs) == 0 || len(rhs) == 0 {
|
||||
if (len(lhs) == 0 && len(rhs) == 0) ||
|
||||
((len(lhs) == 0 || len(rhs) == 0) && matching.FillValues.Rhs == nil && matching.FillValues.Lhs == nil) {
|
||||
return nil, nil // Short-circuit: nothing is going to match.
|
||||
}
|
||||
|
||||
@ -2872,17 +2873,9 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
||||
}
|
||||
matchedSigs := enh.matchedSigs
|
||||
|
||||
// For all lhs samples find a respective rhs sample and perform
|
||||
// the binary operation.
|
||||
var lastErr error
|
||||
for i, ls := range lhs {
|
||||
sigOrd := lhsh[i].sigOrdinal
|
||||
|
||||
rs, found := rightSigs[sigOrd] // Look for a match in the rhs Vector.
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
doBinOp := func(ls Sample, rs Sample, sigOrd int) {
|
||||
// Account for potentially swapped sidedness.
|
||||
fl, fr := ls.F, rs.F
|
||||
hl, hr := ls.H, rs.H
|
||||
@ -2893,7 +2886,7 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
||||
floatValue, histogramValue, keep, info, err := vectorElemBinop(op, fl, fr, hl, hr, pos)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
return
|
||||
}
|
||||
if info != nil {
|
||||
lastErr = info
|
||||
@ -2907,7 +2900,7 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
||||
floatValue = 0.0
|
||||
}
|
||||
case !keep:
|
||||
continue
|
||||
return
|
||||
}
|
||||
metric := resultMetric(ls.Metric, rs.Metric, op, matching, enh)
|
||||
if !ev.enableDelayedNameRemoval && returnBool {
|
||||
@ -2941,6 +2934,44 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
||||
DropName: returnBool,
|
||||
})
|
||||
}
|
||||
|
||||
// For all lhs samples find a respective rhs sample and perform
|
||||
// the binary operation.
|
||||
for i, ls := range lhs {
|
||||
fmt.Println("processing lhs sample:", ls.Metric.String())
|
||||
sigOrd := lhsh[i].sigOrdinal
|
||||
|
||||
rs, found := rightSigs[sigOrd] // Look for a match in the rhs Vector.
|
||||
if !found {
|
||||
if fill := matching.FillValues.Rhs; fill != nil {
|
||||
fmt.Println("using fill rhs value")
|
||||
rs = ls
|
||||
// TODO: Handle histogram fallback values?
|
||||
rs.F = *fill
|
||||
} else {
|
||||
fmt.Println("no match found, continuing")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
doBinOp(ls, rs, sigOrd)
|
||||
}
|
||||
|
||||
// For any rhs samples which have not been matched, check if we need to
|
||||
// perform the operation with a fill value from the lhs.
|
||||
if fill := matching.FillValues.Lhs; fill != nil {
|
||||
for sigOrd, rs := range rightSigs {
|
||||
if _, matched := matchedSigs[sigOrd]; matched {
|
||||
continue // Already matched.
|
||||
}
|
||||
ls := rs
|
||||
// TODO: Handle histogram fallback values?
|
||||
ls.F = *fill
|
||||
|
||||
doBinOp(ls, rs, sigOrd)
|
||||
}
|
||||
}
|
||||
|
||||
return enh.Out, lastErr
|
||||
}
|
||||
|
||||
|
||||
@ -318,6 +318,19 @@ type VectorMatching struct {
|
||||
// Include contains additional labels that should be included in
|
||||
// the result from the side with the lower cardinality.
|
||||
Include []string
|
||||
// Fill-in values to use when a series from one side does not find a match on the other side.
|
||||
FillValues VectorMatchFillValues
|
||||
}
|
||||
|
||||
// VectorMatchFillValues contains the fill values to use for Vector matching
|
||||
// when one side does not find a match on the other side.
|
||||
// When a fill value is nil, no fill is applied for that side, and there
|
||||
// is no output for the match group if there is no match.
|
||||
type VectorMatchFillValues struct {
|
||||
// Rhs is the fill value to use for the right-hand side.
|
||||
Rhs *float64
|
||||
// Lhs is the fill value to use for the left-hand side.
|
||||
Lhs *float64
|
||||
}
|
||||
|
||||
// Visitor allows visiting a Node and its child nodes. The Visit method is
|
||||
|
||||
@ -139,6 +139,9 @@ BOOL
|
||||
BY
|
||||
GROUP_LEFT
|
||||
GROUP_RIGHT
|
||||
FILL
|
||||
LFILL
|
||||
RFILL
|
||||
IGNORING
|
||||
OFFSET
|
||||
SMOOTHED
|
||||
@ -189,7 +192,7 @@ START_METRIC_SELECTOR
|
||||
%type <int> int
|
||||
%type <uint> uint
|
||||
%type <float> number series_value signed_number signed_or_unsigned_number
|
||||
%type <node> step_invariant_expr aggregate_expr aggregate_modifier bin_modifier binary_expr bool_modifier expr function_call function_call_args function_call_body group_modifiers label_matchers matrix_selector number_duration_literal offset_expr anchored_expr smoothed_expr on_or_ignoring paren_expr string_literal subquery_expr unary_expr vector_selector duration_expr paren_duration_expr positive_duration_expr offset_duration_expr
|
||||
%type <node> step_invariant_expr aggregate_expr aggregate_modifier bin_modifier fallback_modifiers binary_expr bool_modifier expr function_call function_call_args function_call_body group_modifiers label_matchers matrix_selector number_duration_literal offset_expr anchored_expr smoothed_expr on_or_ignoring paren_expr string_literal subquery_expr unary_expr vector_selector duration_expr paren_duration_expr positive_duration_expr offset_duration_expr
|
||||
|
||||
%start start
|
||||
|
||||
@ -301,7 +304,7 @@ binary_expr : expr ADD bin_modifier expr { $$ = yylex.(*parser).newBinar
|
||||
|
||||
// Using left recursion for the modifier rules, helps to keep the parser stack small and
|
||||
// reduces allocations.
|
||||
bin_modifier : group_modifiers;
|
||||
bin_modifier : fallback_modifiers;
|
||||
|
||||
bool_modifier : /* empty */
|
||||
{ $$ = &BinaryExpr{
|
||||
@ -345,6 +348,28 @@ group_modifiers: bool_modifier /* empty */
|
||||
}
|
||||
;
|
||||
|
||||
fallback_modifiers: group_modifiers /* empty */
|
||||
| group_modifiers FILL LEFT_PAREN NUMBER RIGHT_PAREN
|
||||
{
|
||||
$$ = $1
|
||||
fill := yylex.(*parser).number($4.Val)
|
||||
$$.(*BinaryExpr).VectorMatching.FillValues.Lhs = &fill
|
||||
$$.(*BinaryExpr).VectorMatching.FillValues.Rhs = &fill
|
||||
}
|
||||
| group_modifiers LFILL LEFT_PAREN NUMBER RIGHT_PAREN
|
||||
{
|
||||
$$ = $1
|
||||
fill := yylex.(*parser).number($4.Val)
|
||||
$$.(*BinaryExpr).VectorMatching.FillValues.Lhs = &fill
|
||||
}
|
||||
| group_modifiers RFILL LEFT_PAREN NUMBER RIGHT_PAREN
|
||||
{
|
||||
$$ = $1
|
||||
fill := yylex.(*parser).number($4.Val)
|
||||
$$.(*BinaryExpr).VectorMatching.FillValues.Rhs = &fill
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
grouping_labels : LEFT_PAREN grouping_label_list RIGHT_PAREN
|
||||
{ $$ = $2 }
|
||||
@ -953,7 +978,7 @@ counter_reset_hint : UNKNOWN_COUNTER_RESET | COUNTER_RESET | NOT_COUNTER_RESET |
|
||||
aggregate_op : AVG | BOTTOMK | COUNT | COUNT_VALUES | GROUP | MAX | MIN | QUANTILE | STDDEV | STDVAR | SUM | TOPK | LIMITK | LIMIT_RATIO;
|
||||
|
||||
// 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 | ATAN2 | LIMITK | LIMIT_RATIO | STEP | ANCHORED | SMOOTHED;
|
||||
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | FILL | LFILL | RFILL | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK | START | END | ATAN2 | LIMITK | LIMIT_RATIO | STEP | ANCHORED | SMOOTHED;
|
||||
|
||||
unary_op : ADD | SUB;
|
||||
|
||||
@ -1141,7 +1166,7 @@ offset_duration_expr : number_duration_literal
|
||||
}
|
||||
| duration_expr
|
||||
;
|
||||
|
||||
|
||||
min_max: MIN | MAX ;
|
||||
|
||||
duration_expr : number_duration_literal
|
||||
@ -1248,14 +1273,14 @@ duration_expr : number_duration_literal
|
||||
;
|
||||
|
||||
paren_duration_expr : LEFT_PAREN duration_expr RIGHT_PAREN
|
||||
{
|
||||
{
|
||||
yylex.(*parser).experimentalDurationExpr($2.(Expr))
|
||||
if durationExpr, ok := $2.(*DurationExpr); ok {
|
||||
durationExpr.Wrapped = true
|
||||
$$ = durationExpr
|
||||
break
|
||||
}
|
||||
$$ = $2
|
||||
$$ = $2
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -137,6 +137,9 @@ var key = map[string]ItemType{
|
||||
"ignoring": IGNORING,
|
||||
"group_left": GROUP_LEFT,
|
||||
"group_right": GROUP_RIGHT,
|
||||
"fill": FILL,
|
||||
"lfill": LFILL,
|
||||
"rfill": RFILL,
|
||||
"bool": BOOL,
|
||||
|
||||
// Preprocessors.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user