mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-11-14 06:46:56 +00:00
test(promql): cover the multi-value timestamp refusal (#9886)
I hereby agree to the terms of the [GreptimeDB CLA](https://github.com/GreptimeTeam/.github/blob/main/CLA.md). ## Refer to a related PR or issue link (optional) Test-only follow-up to #9882. Merge #9882 into `narthex` first, then merge this PR. The PR base remains `feat/narthex-instant-at` until its parent lands. ## What's changed and what's your intention? Add regression coverage for the existing native multi-field `timestamp()` refusal. The net change against the refreshed #9882 is exactly **one file, `src/query/src/promql/native_compile/tests.rs`, with 43 added lines and no production changes**. - `timestamp(x)` over two fields reaches the raw-selector guard; `timestamp(abs(x))` reaches the evaluated-vector guard. Both must return `NotImplemented` naming `timestamp() over a multi-value input` as the reason. - The same two expressions over one field must compile. These positive controls establish that the refusal is about field count rather than blanket rejection of timestamp expressions. - A small local multi-field schema fixture leaves the existing single-field fixture unchanged. The old branch history was not mechanically replayed: only this final test delta is retained atop the new parent. Production refusal, public single-field native timestamp admission and the paired public-planner multi-field fallback test belong to #9882. This PR does not implement multi-field timestamp results or add fallback machinery. ### Verification Verified clean final HEAD **`9a702209747646a68a67fc09a3d44a3c30cfc5cf`**, directly atop #9882 **`24e214b7d4b3d277ce04a7e40d3aaf3d7673c70a`** (rebased onto `narthex=aa30968d43b3`, including #9936). - `make fmt-check` and the exact-parent `git diff --check`: passed. - `cargo check --locked -p query -p promql --all-targets`: passed. - `cargo nextest run --locked -p query -p promql --retries 0 --no-fail-fast`: **1990 passed, 2 skipped**. - `cargo clippy --locked -p query -p promql --all-targets --all-features -- -D warnings`: passed. Old `06695dcf4a5` CI results are not attributed to this rewritten HEAD. The refreshed Checks, Rust CI and Integration CI results for this exact immutable HEAD are required before merge; this PR still follows #9882. The 43 added test lines and their context were compared with the original `3e80f822595..93ad42b76d5` test-only delta. They are identical; only Git blob IDs and hunk line numbers move because #9936 changed the surrounding baseline. Parent standalone Native/Complete Aggregate verification is reported in #9882 rather than attributed to this test-only change. ## PR Checklist - [x] I have written the necessary rustdoc comments. - [x] I have added the necessary unit tests and integration tests. - [ ] This PR requires documentation updates. - [x] API changes are backward compatible. - [x] Schema or data changes are backward compatible. - [ ] This PR needs to be backported to release branches, and I have added the `backport-<target>` labels (e.g. `backport-v1.3` targets `release/v1.3`). This test-only change alters no API, schema, stored data or wire format, and requires no release backport. Refreshed CI runs for this published immutable HEAD are pending: [Checks](https://github.com/GreptimeTeam/greptimedb/actions/runs/40266409294), [Rust CI](https://github.com/GreptimeTeam/greptimedb/actions/runs/40266409205), [Integration CI](https://github.com/GreptimeTeam/greptimedb/actions/runs/40266409248). No merge is performed until these new-HEAD checks pass.
This commit is contained in:
@@ -73,6 +73,19 @@ fn raw_schema() -> Arc<SeriesSchema> {
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<SeriesSchema> {
|
||||
Arc::new(SeriesSchema {
|
||||
fields: (0..count)
|
||||
.map(|index| FieldSpec {
|
||||
name: format!("value_{index}").into(),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.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(
|
||||
|
||||
Reference in New Issue
Block a user