Convert multiple grouping expressions into one [`GroupingSet::GroupingSets`],\ if the grouping expression does not contain [`Expr::GroupingSet`] or only has one expression,\ no conversion will be performed. e.g. person.id,\ GROUPING SETS ((person.age, person.salary),(person.age)),\ ROLLUP(person.state, person.birth_date) => GROUPING SETS (\ (person.id, person.age, person.salary),\ (person.id,
(group_expr: Vec<Expr>)
| 200 | /// (person.id, person.age, person.state, person.birth_date)\ |
| 201 | /// ) |
| 202 | pub fn enumerate_grouping_sets(group_expr: Vec<Expr>) -> Result<Vec<Expr>> { |
| 203 | let has_grouping_set = group_expr |
| 204 | .iter() |
| 205 | .any(|expr| matches!(expr, Expr::GroupingSet(_))); |
| 206 | if !has_grouping_set || group_expr.len() == 1 { |
| 207 | return Ok(group_expr); |
| 208 | } |
| 209 | // Only process mix grouping sets |
| 210 | let partial_sets = group_expr |
| 211 | .iter() |
| 212 | .map(|expr| { |
| 213 | let exprs = match expr { |
| 214 | Expr::GroupingSet(GroupingSet::GroupingSets(grouping_sets)) => { |
| 215 | check_grouping_sets_size_limit(grouping_sets.len())?; |
| 216 | grouping_sets.iter().map(|e| e.iter().collect()).collect() |
| 217 | } |
| 218 | Expr::GroupingSet(GroupingSet::Cube(group_exprs)) => { |
| 219 | let grouping_sets = powerset(group_exprs)?; |
| 220 | check_grouping_sets_size_limit(grouping_sets.len())?; |
| 221 | grouping_sets |
| 222 | } |
| 223 | Expr::GroupingSet(GroupingSet::Rollup(group_exprs)) => { |
| 224 | let size = group_exprs.len(); |
| 225 | let slice = group_exprs.as_slice(); |
| 226 | check_grouping_sets_size_limit(size * (size + 1) / 2 + 1)?; |
| 227 | (0..(size + 1)) |
| 228 | .map(|i| slice[0..i].iter().collect()) |
| 229 | .collect() |
| 230 | } |
| 231 | expr => vec![vec![expr]], |
| 232 | }; |
| 233 | Ok(exprs) |
| 234 | }) |
| 235 | .collect::<Result<Vec<_>>>()?; |
| 236 | |
| 237 | // Cross Join |
| 238 | let grouping_sets = partial_sets |
| 239 | .into_iter() |
| 240 | .map(Ok) |
| 241 | .reduce(|l, r| cross_join_grouping_sets(&l?, &r?)) |
| 242 | .transpose()? |
| 243 | .map(|e| { |
| 244 | e.into_iter() |
| 245 | .map(|e| e.into_iter().cloned().collect()) |
| 246 | .collect() |
| 247 | }) |
| 248 | .unwrap_or_default(); |
| 249 | |
| 250 | Ok(vec![Expr::GroupingSet(GroupingSet::GroupingSets( |
| 251 | grouping_sets, |
| 252 | ))]) |
| 253 | } |
| 254 | |
| 255 | /// Find all distinct exprs in a list of group by expressions. If the |
| 256 | /// first element is a `GroupingSet` expression then it must be the only expr. |
searching dependent graphs…