From 98d67fccf1194ff90e7b7f5560276aab2a8908ea Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 10 Sep 2026 16:34:08 -0400 Subject: [PATCH] feat: add MetricsQL range functions --- src/parser/function.rs | 25 ++++++++++++++++++++++++- src/parser/parse.rs | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/parser/function.rs b/src/parser/function.rs index 094fbf7..5dc5e9b 100644 --- a/src/parser/function.rs +++ b/src/parser/function.rs @@ -247,7 +247,23 @@ lazy_static! { ValueType::Vector, false ), + // MetricsQL extension. + function!( + "distinct_over_time", + vec![ValueType::Matrix], + 0, + ValueType::Vector, + false + ), function!("end", vec![], 0, ValueType::Scalar, true), + // MetricsQL extension. + function!( + "entropy_over_time", + vec![ValueType::Matrix], + 0, + ValueType::Vector, + false + ), function!("exp", vec![ValueType::Vector], 0, ValueType::Vector, false), function!( "first_over_time", @@ -668,7 +684,6 @@ mod tests { let rate = get_function("rate").unwrap(); assert_eq!(rate.variadic, 0); assert!(!rate.experimental); - for func_name in ["max_of", "min_of"] { let func = get_function(func_name).unwrap(); assert_eq!(func.arg_types, vec![ValueType::Scalar, ValueType::Scalar]); @@ -676,5 +691,13 @@ mod tests { assert_eq!(func.return_type, ValueType::Scalar); assert!(func.experimental); } + + for func_name in ["distinct_over_time", "entropy_over_time"] { + let func = get_function(func_name).unwrap(); + assert_eq!(func.arg_types, vec![ValueType::Matrix]); + assert_eq!(func.variadic, 0); + assert_eq!(func.return_type, ValueType::Vector); + assert!(!func.experimental); + } } } diff --git a/src/parser/parse.rs b/src/parser/parse.rs index 3d706d5..305f25a 100644 --- a/src/parser/parse.rs +++ b/src/parser/parse.rs @@ -1345,6 +1345,30 @@ mod tests { Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex)) }) }), + ("distinct_over_time(some_metric[5m])", { + Expr::new_matrix_selector( + Expr::from(VectorSelector::from("some_metric")), + duration::MINUTE_DURATION * 5, + ) + .and_then(|ex| { + Expr::new_call( + get_function("distinct_over_time").unwrap(), + FunctionArgs::new_args(ex), + ) + }) + }), + ("entropy_over_time(some_metric[5m])", { + Expr::new_matrix_selector( + Expr::from(VectorSelector::from("some_metric")), + duration::MINUTE_DURATION * 5, + ) + .and_then(|ex| { + Expr::new_call( + get_function("entropy_over_time").unwrap(), + FunctionArgs::new_args(ex), + ) + }) + }), ("round(some_metric)", { let ex = Expr::from(VectorSelector::from("some_metric")); Expr::new_call(get_function("round").unwrap(), FunctionArgs::new_args(ex))