fix(promql): default a stepless subquery to a one-minute step (#9481)

* fix(promql): default a stepless subquery to a one-minute step

`x[5m:]` evaluated the inner expression at the query step, which is 1s
for instant queries. Prometheus uses the evaluation interval, one minute
by default.

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* test(promql): cover the default subquery step

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* test(promql): cover the default subquery step in a range query

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

---------

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
(cherry picked from commit 845fc0af9c)
Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
dennis zhuang
2026-10-12 12:49:21 +00:00
committed by WenyXu
parent ce4621cbb2
commit 5fe2a57adb
4 changed files with 82 additions and 11 deletions
+4 -3
View File
@@ -587,9 +587,10 @@ impl PromPlanner {
};
let current_interval = self.ctx.interval;
if let Some(step) = step {
self.ctx.interval = step.as_millis() as _;
}
self.ctx.interval = match step {
Some(step) => step.as_millis() as _,
None => DEFAULT_SUBQUERY_STEP_MS,
};
ensure!(self.ctx.interval > 0, ZeroRangeSelectorSnafu);
let current_start = self.ctx.start;
let current_end = self.ctx.end;
-8
View File
@@ -5682,14 +5682,6 @@ async fn subquery_rejects_invalid_range_and_zero_step() {
matches!(&err, crate::promql::error::Error::ZeroRangeSelector { .. }),
"{err}"
);
// An omitted child step inherits the zero parent step.
let err = plan_subquery_offset_probe("sum_over_time(subquery_offset_offgrid[5s:])", 60, 60, 0)
.await
.unwrap_err();
assert!(
matches!(&err, crate::promql::error::Error::ZeroRangeSelector { .. }),
"{err}"
);
}
/// Rejects nonempty child windows whose derived millisecond bounds are unrepresentable.