Resolve a GROUP BY expression that references a SELECT alias or ordinal. `GROUP BY b` where `b` is an alias → returns the aliased expression. `GROUP BY 1` → returns the 1st SELECT expression (0-indexed).
(
expr: &ast::Expr,
select_items: &'a [ast::SelectItem],
)
| 176 | /// `GROUP BY b` where `b` is an alias → returns the aliased expression. |
| 177 | /// `GROUP BY 1` → returns the 1st SELECT expression (0-indexed). |
| 178 | fn resolve_group_by_expr<'a>( |
| 179 | expr: &ast::Expr, |
| 180 | select_items: &'a [ast::SelectItem], |
| 181 | ) -> Option<&'a ast::Expr> { |
| 182 | match expr { |
| 183 | ast::Expr::Identifier(ident) => { |
| 184 | let alias_name = normalize_ident(ident); |
| 185 | select_items.iter().find_map(|item| { |
| 186 | if let ast::SelectItem::ExprWithAlias { expr, alias } = item |
| 187 | && normalize_ident(alias) == alias_name |
| 188 | { |
| 189 | Some(expr) |
| 190 | } else { |
| 191 | None |
| 192 | } |
| 193 | }) |
| 194 | } |
| 195 | ast::Expr::Value(v) => { |
| 196 | if let ast::Value::Number(n, _) = &v.value |
| 197 | && let Ok(idx) = n.parse::<usize>() |
| 198 | && idx >= 1 |
| 199 | && idx <= select_items.len() |
| 200 | { |
| 201 | match &select_items[idx - 1] { |
| 202 | ast::SelectItem::UnnamedExpr(e) => Some(e), |
| 203 | ast::SelectItem::ExprWithAlias { expr, .. } => Some(expr), |
| 204 | _ => None, |
| 205 | } |
| 206 | } else { |
| 207 | None |
| 208 | } |
| 209 | } |
| 210 | _ => None, |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | /// Extract the bucket interval from a time_bucket() call. |
| 215 | /// |