updates due to review comments

Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
This commit is contained in:
György Krajcsovits 2025-02-11 17:29:21 +01:00
parent 623f4e02cc
commit 0efd36ebd6
4 changed files with 20 additions and 7 deletions

View file

@ -303,6 +303,17 @@ When querying for samples in the past, a negative offset will enable temporal co
Note that this allows a query to look ahead of its evaluation time.
_Notes about the experimental time expressions:_
The offset may be a time expression in parenthesis. A time expression is
different from a normal expression in that it must yield a scalar and
must not query series. The scalar resulting from the time expression will be
used as the offset in seconds. The `time()` function can only be called outside
subqueries. For example, 5 minute offset may be calculated from adding 2 minutes
and 180 seconds together:
http_requests_total offset (2m + 180)
### @ modifier
The `@` modifier allows changing the evaluation time for individual instant

View file

@ -128,7 +128,7 @@ func (e ErrTimeExprNotAFloat) Error() string {
var (
// ErrTimeExprUsesStorage is returned if a time expression
// (timestamp/duration) calculation includes vector/range selector.
ErrTimeExprUsesStorage = errors.New("time expression must not use storage")
ErrTimeExprUsesStorage = errors.New("time expression must not query for series")
// ErrTimeExprDependsOnEvalTime is returned if a time expression
// depends on the evaluation time, which is only allowed for the top level
// time expressions.
@ -567,7 +567,7 @@ func (tev timeExprVisitor) Visit(node parser.Node, path []parser.Node) (parser.V
if nl, ok := expr.(*parser.NumberLiteral); ok {
return nl.Val, nil
}
val, err := tev.ev.timeValueOf(expr)
val, err := tev.ev.scalarValueOf(expr)
if err != nil {
return 0, err
}
@ -3988,14 +3988,16 @@ func (ev *evaluator) gatherVector(ts int64, input Matrix, output Vector, bufHelp
return output, bufHelpers
}
// timeValueOf calculates the scalar time value of an expression in float64.
func (ev *evaluator) timeValueOf(e parser.Expr) (float64, error) {
// scalarValueOf calculates the scalar value of an expression in float64.
// Use case for this is to be able to calculate offset durations,
// timestamp, range duration, etc. from scalar expressions.
func (ev *evaluator) scalarValueOf(e parser.Expr) (float64, error) {
if e == nil {
return 0, nil
}
if ev.querier != nil {
panic("evaulator does not disallow querier for time expressions")
panic("evaulator does not allow querier for time expressions")
}
// Shortcut for number literals.

View file

@ -26,7 +26,7 @@ type Function struct {
// the current evaluation timestamp is. For example time().
EvalTimeDependent bool
// StorageDependent means that the out of the function depends on the
// StorageDependent means that the output of the function depends on the
// content of TSDB at the time. For example info().
StorageDependent bool
}

View file

@ -31,6 +31,6 @@ eval instant at 10m metric offset (5m + 1m)
metric{} 4
# The time() function is allowed on top level.
# Value at 10m-(1) == 9.59
# Value at 10m-(1) == 9m59s
eval instant at 10m metric offset (time() != bool 0 + time() == bool 0)
metric{} 9