From 9a702209747646a68a67fc09a3d44a3c30cfc5cf Mon Sep 17 00:00:00 2001 From: discord9 <55937128+discord9@users.noreply.github.com> Date: Mon, 26 Oct 2026 11:25:44 +0800 Subject: [PATCH] test(promql): cover the multi-value timestamp refusal Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --- src/query/src/promql/native_compile/tests.rs | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/query/src/promql/native_compile/tests.rs b/src/query/src/promql/native_compile/tests.rs index 4839048e84a..1ae05ff55ec 100644 --- a/src/query/src/promql/native_compile/tests.rs +++ b/src/query/src/promql/native_compile/tests.rs @@ -73,6 +73,19 @@ fn raw_schema() -> Arc { }) } +/// The same layout with `count` fields, for the shapes whose answer depends on how many a scan holds. +fn raw_schema_with_fields(count: usize) -> Arc { + Arc::new(SeriesSchema { + fields: (0..count) + .map(|index| FieldSpec { + name: format!("value_{index}").into(), + }) + .collect::>() + .into(), + eval_grid: None, + }) +} + /// A statement over 100 seconds in 5-second steps, which is 21 grid points. fn eval_stmt(query: &str) -> EvalStmt { eval_stmt_over(query, Duration::from_secs(100)) @@ -4537,6 +4550,36 @@ fn an_invalid_label_replace_expression_fails_the_statement() { assert!(matches!(error, DataFusionError::Plan(_)), "{error}"); } +/// `timestamp` reports one value per input field, and the native node reports the time of the sample +/// each field was selected from. A table with several data fields would need that node to say which +/// field's sample it means, so the compiler declines the shape instead of answering with one +/// field's timestamps under every field's name. +#[test] +fn timestamp_multi_field_input_is_not_supported_natively() { + for query in ["timestamp(x)", "timestamp(abs(x))"] { + let error = compile( + &eval_stmt(query), + raw_schema_with_fields(2), + SeriesOrdering::KeyThenTime, + ) + .unwrap_err(); + assert!( + matches!(&error, DataFusionError::NotImplemented(_)), + "`{query}` is a shape this compiler declines: {error}" + ); + assert!( + error + .to_string() + .contains("timestamp() over a multi-value input"), + "`{query}` did not name the field count as the reason: {error}" + ); + } + // One field is the shape the node does answer, so the refusal is about the field count. + for query in ["timestamp(x)", "timestamp(abs(x))"] { + compile(&eval_stmt(query), raw_schema(), SeriesOrdering::KeyThenTime) + .unwrap_or_else(|error| panic!("`{query}` over one field was refused: {error}")); + } +} #[test] fn selector_requirements_capture_bounds_and_source_occurrence() { let compiled = compile_selectors(