[Feature request] Support Prometheus-compatible PromQL rate(), irate(), increase(), and delta() for range vectors
- Vorherrschende Sprache
- Java
- Sterne
- 6.4k
- Forks
- 1.2k
- Ø Merge
- 1 T. 23 Std.
- Gemergte PRs (30 T.)
- 115
Beschreibung
### Search before asking
- [x] I searched in the [issues](https://github.com/apache/iotdb/issues) and found nothing similar.
### Motivation
## Description
IoTDB should support Prometheus-compatible semantics for the PromQL `rate()`, `irate()`, `increase()`, and `delta()` functions on range vectors.
The expected behavior should follow Prometheus:
- `rate(v range-vector)` returns the per-second average rate of increase over the selected range.
- `irate(v range-vector)` returns the per-second instant rate based on the last two samples in the selected range.
- `increase(v range-vector)` returns the total increase over the selected range.
- `delta(v range-vector)` returns the difference between the first and last values over the selected range.
- `rate()`, `irate()`, and `increase()` should be used with counters and should handle counter resets correctly.
- `delta()` should be used with gauges and should not apply counter-reset correction.
- `rate()`, `increase()`, and `delta()` should use all samples in the range and extrapolate to the range boundaries.
- `irate()` should use only the last two samples and should not extrapolate to range boundaries.
## Expected Implementation Semantics
For `rate()` on float counters:
1. Require at least two samples.
2. Compute the raw increase as `last - first`.
3. For each adjacent sample pair, detect counter reset when `current < previous`.
4. For each detected reset, add the previous value to the corrected increase.
5. If start timestamp metadata is available, also treat start timestamp reset as a counter reset.
6. Apply Prometheus-compatible boundary extrapolation.
7. Divide by the full range duration in seconds.
For `increase()` on float counters:
1. Require at least two samples.
2. Use the same counter-reset correction and boundary extrapolation logic as `rate()`.
3. Return the extrapolated total increase over the range.
4. Do not divide by the range duration.
5. The result should be equivalent to `rate(v) * rangeDurationSeconds`.
For `irate()` on float counters:
1. Require at least two samples.
2. Use only the last two samples in the range.
3. If no reset is detected, return `(last - previous) / intervalSeconds`.
4. If reset is detected, return `last / intervalSeconds`.
5. Do not perform range-boundary extrapolation.
For `delta()` on float gauges:
1. Require at least two samples.
2. Compute the raw delta as `last - first`.
3. Do not apply counter-reset correction.
4. Apply Prometheus-compatible boundary extrapolation to cover the full range.
5. Return the extrapolated delta directly.
6. Do not divide by the range duration.
## Test Cases
Please add compatibility tests for:
- `rate()` without reset.
- `rate()` with one counter reset.
- `rate()` with multiple counter resets.
- `rate()` boundary extrapolation when samples are close to the range boundaries.
- `rate()` boundary extrapolation when samples are far from the range boundaries.
- `rate()` counter zero-point extrapolation guard.
- `increase()` without reset.
- `increase()` with one counter reset.
- `increase()` with multiple counter resets.
- `increase()` boundary extrapolation.
- `increase()` producing the same value as `rate(v) * rangeDurationSeconds`.
- `irate()` without reset.
- `irate()` with reset between the last two samples.
- `irate()` ignoring older samples except for selecting the last two points.
- `delta()` with increasing gauge values.
- `delta()` with decreasing gauge values.
- `delta()` boundary extrapolation.
- `delta()` not treating value decreases as counter resets.
- Empty result when fewer than two samples are available.
## References
- Prometheus `rate()` documentation: https://prometheus.io/docs/prometheus/latest/querying/functions/#rate
- Prometheus `irate()` documentation: https://prometheus.io/docs/prometheus/latest/querying/functions/#irate
- Prometheus `increase()` documentation: https://prometheus.io/docs/prometheus/latest/querying/functions/#increase
- Prometheus `delta()` documentation: https://prometheus.io/docs/prometheus/latest/querying/functions/#delta
- Prometheus `resets()` documentation: https://prometheus.io/docs/prometheus/latest/querying/functions/#resets
- Prometheus implementation: https://github.com/prometheus/prometheus/blob/main/promql/functions.go
### Solution
_No response_
### Alternatives
_No response_
### Are you willing to submit a PR?
- [ ] I'm willing to submit a PR!
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.