Extract timeseries-specific parameters from GROUP BY (bucket interval, group columns). Returns `(Some(interval_ms), group_columns)` if a `time_bucket()` call is found, or `(None, empty)` otherwise. Non-timeseries engines ignore these values.
(
raw_group_by: &GroupByExpr,
select_items: &[ast::SelectItem],
functions: &FunctionRegistry,
)
| 125 | /// Returns `(Some(interval_ms), group_columns)` if a `time_bucket()` call is found, |
| 126 | /// or `(None, empty)` otherwise. Non-timeseries engines ignore these values. |
| 127 | fn extract_timeseries_params( |
| 128 | raw_group_by: &GroupByExpr, |
| 129 | select_items: &[ast::SelectItem], |
| 130 | functions: &FunctionRegistry, |
| 131 | ) -> Result<(Option<i64>, Vec<String>)> { |
| 132 | let mut bucket_interval_ms: Option<i64> = None; |
| 133 | let mut group_columns = Vec::new(); |
| 134 | |
| 135 | if let GroupByExpr::Expressions(exprs, _) = raw_group_by { |
| 136 | for expr in exprs { |
| 137 | let resolved = resolve_group_by_expr(expr, select_items); |
| 138 | let check_expr = resolved.unwrap_or(expr); |
| 139 | |
| 140 | if let Some(interval) = try_extract_time_bucket(check_expr, functions)? { |
| 141 | bucket_interval_ms = Some(interval); |
| 142 | continue; |
| 143 | } |
| 144 | |
| 145 | if let ast::Expr::Identifier(ident) = expr { |
| 146 | group_columns.push(normalize_ident(ident)); |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | Ok((bucket_interval_ms, group_columns)) |
| 152 | } |
| 153 | |
| 154 | /// Check if an expression is a time_bucket() call and extract the interval. |
| 155 | fn try_extract_time_bucket(expr: &ast::Expr, functions: &FunctionRegistry) -> Result<Option<i64>> { |
no test coverage detected