mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
[metricsql] for subqueries fixed behavior of functions that use query time range in their logic (like start
, end
, and running_*
), from now on when using in subqueries they respect time range from query parameters (#5794)
This commit is contained in:
parent
7332431b90
commit
881dffd6a2
3 changed files with 52 additions and 9 deletions
|
@ -111,6 +111,11 @@ type EvalConfig struct {
|
||||||
End int64
|
End int64
|
||||||
Step int64
|
Step int64
|
||||||
|
|
||||||
|
// RealStart contains the original start of the interval when executed in subqueries (because Start can be changed for subqueries)
|
||||||
|
RealStart int64
|
||||||
|
// RealEnd contains the original end of the interval when executed in subqueries (because End can be changed for subqueries)
|
||||||
|
RealEnd int64
|
||||||
|
|
||||||
// MaxSeries is the maximum number of time series, which can be scanned by the query.
|
// MaxSeries is the maximum number of time series, which can be scanned by the query.
|
||||||
// Zero means 'no limit'
|
// Zero means 'no limit'
|
||||||
MaxSeries int
|
MaxSeries int
|
||||||
|
@ -152,7 +157,17 @@ type EvalConfig struct {
|
||||||
func copyEvalConfig(src *EvalConfig) *EvalConfig {
|
func copyEvalConfig(src *EvalConfig) *EvalConfig {
|
||||||
var ec EvalConfig
|
var ec EvalConfig
|
||||||
ec.Start = src.Start
|
ec.Start = src.Start
|
||||||
|
if ec.RealStart > 0 {
|
||||||
|
ec.RealStart = src.RealStart
|
||||||
|
} else {
|
||||||
|
ec.RealStart = src.Start
|
||||||
|
}
|
||||||
ec.End = src.End
|
ec.End = src.End
|
||||||
|
if ec.RealEnd > 0 {
|
||||||
|
ec.RealEnd = src.RealEnd
|
||||||
|
} else {
|
||||||
|
ec.RealEnd = src.End
|
||||||
|
}
|
||||||
ec.Step = src.Step
|
ec.Step = src.Step
|
||||||
ec.MaxSeries = src.MaxSeries
|
ec.MaxSeries = src.MaxSeries
|
||||||
ec.MaxPointsPerSeries = src.MaxPointsPerSeries
|
ec.MaxPointsPerSeries = src.MaxPointsPerSeries
|
||||||
|
|
|
@ -1248,8 +1248,13 @@ func newTransformFuncRunning(rf func(a, b float64, idx int) float64) transformFu
|
||||||
prevValue := values[0]
|
prevValue := values[0]
|
||||||
values = values[1:]
|
values = values[1:]
|
||||||
for i, v := range values {
|
for i, v := range values {
|
||||||
if !math.IsNaN(v) {
|
if tfa.ec.RealEnd > 0 && ts.Timestamps[i] > tfa.ec.RealEnd {
|
||||||
prevValue = rf(prevValue, v, i+1)
|
break
|
||||||
|
}
|
||||||
|
if ts.Timestamps[i] >= tfa.ec.RealStart {
|
||||||
|
if !math.IsNaN(v) {
|
||||||
|
prevValue = rf(prevValue, v, i+1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
values[i] = prevValue
|
values[i] = prevValue
|
||||||
}
|
}
|
||||||
|
@ -1265,7 +1270,7 @@ func newTransformFuncRange(rf func(a, b float64, idx int) float64) transformFunc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
setLastValues(rvs)
|
setLastValues(tfa, rvs)
|
||||||
return rvs, nil
|
return rvs, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1539,7 +1544,7 @@ func transformRangeQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
|
||||||
}
|
}
|
||||||
a.A = values
|
a.A = values
|
||||||
putFloat64s(a)
|
putFloat64s(a)
|
||||||
setLastValues(rvs)
|
setLastValues(tfa, rvs)
|
||||||
return rvs, nil
|
return rvs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1554,9 +1559,14 @@ func transformRangeFirst(tfa *transformFuncArg) ([]*timeseries, error) {
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
vFirstSet := false
|
||||||
vFirst := values[0]
|
vFirst := values[0]
|
||||||
for i, v := range values {
|
for i, v := range values {
|
||||||
if math.IsNaN(v) {
|
if !vFirstSet && ts.Timestamps[i] >= tfa.ec.RealStart {
|
||||||
|
vFirst = v
|
||||||
|
vFirstSet = true
|
||||||
|
}
|
||||||
|
if !vFirstSet && math.IsNaN(v) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
values[i] = vFirst
|
values[i] = vFirst
|
||||||
|
@ -1571,17 +1581,28 @@ func transformRangeLast(tfa *transformFuncArg) ([]*timeseries, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rvs := args[0]
|
rvs := args[0]
|
||||||
setLastValues(rvs)
|
setLastValues(tfa, rvs)
|
||||||
return rvs, nil
|
return rvs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLastValues(tss []*timeseries) {
|
func setLastValues(tfa *transformFuncArg, tss []*timeseries) {
|
||||||
for _, ts := range tss {
|
for _, ts := range tss {
|
||||||
values := skipTrailingNaNs(ts.Values)
|
values := skipTrailingNaNs(ts.Values)
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
vLast := values[len(values)-1]
|
vLast := values[len(values)-1]
|
||||||
|
if tfa.ec.RealEnd > 0 {
|
||||||
|
for i := len(values) - 1; i >= 0; i-- {
|
||||||
|
if math.IsNaN(values[i]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ts.Timestamps[i] > tfa.ec.RealEnd {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
vLast = values[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
for i, v := range values {
|
for i, v := range values {
|
||||||
if math.IsNaN(v) {
|
if math.IsNaN(v) {
|
||||||
continue
|
continue
|
||||||
|
@ -2713,11 +2734,17 @@ func transformStep(tfa *transformFuncArg) float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func transformStart(tfa *transformFuncArg) float64 {
|
func transformStart(tfa *transformFuncArg) float64 {
|
||||||
return float64(tfa.ec.Start) / 1e3
|
if tfa.ec.RealStart == 0 {
|
||||||
|
return float64(tfa.ec.Start) / 1e3
|
||||||
|
}
|
||||||
|
return float64(tfa.ec.RealStart) / 1e3
|
||||||
}
|
}
|
||||||
|
|
||||||
func transformEnd(tfa *transformFuncArg) float64 {
|
func transformEnd(tfa *transformFuncArg) float64 {
|
||||||
return float64(tfa.ec.End) / 1e3
|
if tfa.ec.RealEnd == 0 {
|
||||||
|
return float64(tfa.ec.End) / 1e3
|
||||||
|
}
|
||||||
|
return float64(tfa.ec.RealEnd) / 1e3
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyTimeseries returns a copy of tss.
|
// copyTimeseries returns a copy of tss.
|
||||||
|
|
|
@ -41,6 +41,7 @@ See also [LTS releases](https://docs.victoriametrics.com/LTS-releases.html).
|
||||||
* BUGFIX: fix the misleading error `0ms is out of allowed range [0 ...` when passing `step=0` to [/api/v1/query](https://docs.victoriametrics.com/keyconcepts/#instant-query)
|
* BUGFIX: fix the misleading error `0ms is out of allowed range [0 ...` when passing `step=0` to [/api/v1/query](https://docs.victoriametrics.com/keyconcepts/#instant-query)
|
||||||
or [/api/v1/query_range](https://docs.victoriametrics.com/keyconcepts/#range-query). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5795).
|
or [/api/v1/query_range](https://docs.victoriametrics.com/keyconcepts/#range-query). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5795).
|
||||||
* BUGFIX: [vmalert](https://docs.victoriametrics.com/#vmalert): consistently sort groups by name and filename on `/groups` page in UI. This should prevent non-deterministic sorting for groups with identical names.
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/#vmalert): consistently sort groups by name and filename on `/groups` page in UI. This should prevent non-deterministic sorting for groups with identical names.
|
||||||
|
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): For subqueries fix behavior of functions that use query time range in their logic (like `start`, `end`, and `running_*`), from now on when using in subqueries they respect time range from query parameters. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5794) for details.
|
||||||
|
|
||||||
## [v1.98.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.98.0)
|
## [v1.98.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.98.0)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue