From bc06106f0cd06678d9191180ad568e3cdc09cbf2 Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Thu, 8 Jun 2023 12:47:57 +1000 Subject: [PATCH] chore: duration_expr_to_nanoseconds should support `now` This could appear in a group by clause, such as: ``` GROUP BY time(5s, now()) ``` --- influxdb_influxql_parser/src/time_range.rs | 42 ++++++++++++---------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/influxdb_influxql_parser/src/time_range.rs b/influxdb_influxql_parser/src/time_range.rs index 54f48b5e00..eedc730d7c 100644 --- a/influxdb_influxql_parser/src/time_range.rs +++ b/influxdb_influxql_parser/src/time_range.rs @@ -391,10 +391,8 @@ impl TimeRange { /// Simplifies an InfluxQL duration `expr` to a nanosecond interval represented as an `i64`. pub fn duration_expr_to_nanoseconds(ctx: &ReduceContext, expr: &Expr) -> Result { - match reduce_expr(&ctx, expr)? { - Expr::Literal(Literal::Duration(v)) => Ok(*v), - Expr::Literal(Literal::Float(v)) => Ok(v as i64), - Expr::Literal(Literal::Integer(v)) => Ok(v), + match reduce_time_expr(&ctx, expr)? { + Expr::Literal(Literal::Timestamp(v)) => Ok(v.timestamp_nanos()), _ => error::expr("invalid duration expression"), } } @@ -443,7 +441,7 @@ pub struct ReduceContext { pub tz: Option, } -/// Simplify the time range expression. +/// Simplify the time range expression and return a literal [timestamp](Timestamp). fn reduce_time_expr(ctx: &ReduceContext, expr: &Expr) -> ExprResult { match reduce_expr(ctx, expr)? { expr @ Expr::Literal(Literal::Timestamp(_)) => Ok(expr), @@ -731,21 +729,26 @@ mod test { use chrono::{NaiveDate, NaiveDateTime, NaiveTime, Offset, Utc}; use test_helpers::assert_error; + /// Return a `ReduceContext` with a value of + /// now set to `2023-01-01T00:00:00Z` / `1672531200000000000` + /// and not timezone. + fn reduce_context() -> ReduceContext { + ReduceContext { + now: Some(Timestamp::from_utc( + NaiveDateTime::new( + NaiveDate::from_ymd_opt(2023, 1, 1).unwrap(), + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), + ), + Utc.fix(), + )), + tz: None, + } + } + #[test] fn test_split_cond() { fn split_exprs(s: &str) -> Result<(Option, TimeRange), ExprError> { - // 2023-01-01T00:00:00Z == 1672531200000000000 - let ctx = ReduceContext { - now: Some(Timestamp::from_utc( - NaiveDateTime::new( - NaiveDate::from_ymd_opt(2023, 1, 1).unwrap(), - NaiveTime::from_hms_opt(0, 0, 0).unwrap(), - ), - Utc.fix(), - )), - tz: None, - }; - + let ctx = reduce_context(); let cond: ConditionalExpression = s.parse().unwrap(); split_cond(&ctx, &cond) } @@ -1013,13 +1016,14 @@ mod test { #[test] fn test_expr_to_duration() { fn parse(s: &str) -> Result { + let ctx = reduce_context(); let expr = s .parse::() .unwrap() .expr() .unwrap() .clone(); - duration_expr_to_nanoseconds(&ReduceContext::default(), &expr) + duration_expr_to_nanoseconds(&ctx, &expr) } let cases = vec![ @@ -1028,6 +1032,8 @@ mod test { ("5d10ms", 432_000_010_000_000), ("-2d10ms", -172800010000000), ("-2d10ns", -172800000000010), + ("now()", 1672531200000000000), + ("'2023-01-01T00:00:00Z'", 1672531200000000000), ]; for (interval_str, exp) in cases {