diff --git a/src/query/src/promql/planner.rs b/src/query/src/promql/planner.rs index 5867301f972..972f04b9ccf 100644 --- a/src/query/src/promql/planner.rs +++ b/src/query/src/promql/planner.rs @@ -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; diff --git a/src/query/src/promql/planner/test.rs b/src/query/src/promql/planner/test.rs index 19de1098288..f78162d8fdb 100644 --- a/src/query/src/promql/planner/test.rs +++ b/src/query/src/promql/planner/test.rs @@ -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. diff --git a/tests/cases/standalone/common/promql/subquery_default_step.result b/tests/cases/standalone/common/promql/subquery_default_step.result new file mode 100644 index 00000000000..47008660cad --- /dev/null +++ b/tests/cases/standalone/common/promql/subquery_default_step.result @@ -0,0 +1,53 @@ +-- A subquery without a step uses the evaluation interval (one minute by +-- default in Prometheus), not the query step. Expected results are from Prometheus 3. +create table subquery_default_step ( + ts timestamp time index, + val double, + host string primary key +); + +Affected Rows: 0 + +insert into subquery_default_step values + (0, 1.0, 'a'), + (60000, 1.0, 'a'), + (120000, 1.0, 'a'), + (180000, 1.0, 'a'), + (240000, 1.0, 'a'), + (300000, 1.0, 'a'); + +Affected Rows: 6 + +tql eval (300, 300, '1s') count_over_time(subquery_default_step[5m:]); + ++---------------------+------------------------------------+------+ +| ts | prom_count_over_time(ts_range,val) | host | ++---------------------+------------------------------------+------+ +| 1970-01-01T00:05:00 | 5.0 | a | ++---------------------+------------------------------------+------+ + +tql eval (300, 300, '1s') count_over_time(subquery_default_step[5m:30s]); + ++---------------------+------------------------------------+------+ +| ts | prom_count_over_time(ts_range,val) | host | ++---------------------+------------------------------------+------+ +| 1970-01-01T00:05:00 | 10.0 | a | ++---------------------+------------------------------------+------+ + +-- The outer range query keeps its own step around the subquery's default step. +tql eval (300, 360, '15s') count_over_time(subquery_default_step[5m:]); + ++---------------------+------------------------------------+------+ +| ts | prom_count_over_time(ts_range,val) | host | ++---------------------+------------------------------------+------+ +| 1970-01-01T00:05:00 | 5.0 | a | +| 1970-01-01T00:05:15 | 5.0 | a | +| 1970-01-01T00:05:30 | 5.0 | a | +| 1970-01-01T00:05:45 | 5.0 | a | +| 1970-01-01T00:06:00 | 5.0 | a | ++---------------------+------------------------------------+------+ + +drop table subquery_default_step; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/promql/subquery_default_step.sql b/tests/cases/standalone/common/promql/subquery_default_step.sql new file mode 100644 index 00000000000..fb1acb5f45b --- /dev/null +++ b/tests/cases/standalone/common/promql/subquery_default_step.sql @@ -0,0 +1,25 @@ +-- A subquery without a step uses the evaluation interval (one minute by +-- default in Prometheus), not the query step. Expected results are from Prometheus 3. + +create table subquery_default_step ( + ts timestamp time index, + val double, + host string primary key +); + +insert into subquery_default_step values + (0, 1.0, 'a'), + (60000, 1.0, 'a'), + (120000, 1.0, 'a'), + (180000, 1.0, 'a'), + (240000, 1.0, 'a'), + (300000, 1.0, 'a'); + +tql eval (300, 300, '1s') count_over_time(subquery_default_step[5m:]); + +tql eval (300, 300, '1s') count_over_time(subquery_default_step[5m:30s]); + +-- The outer range query keeps its own step around the subquery's default step. +tql eval (300, 360, '15s') count_over_time(subquery_default_step[5m:]); + +drop table subquery_default_step;