MCPcopy Create free account
hub / github.com/apache/datafusion / enumerate_grouping_sets

Function enumerate_grouping_sets

datafusion/expr/src/utils.rs:202–253  ·  view source on GitHub ↗

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>)

Source from the content-addressed store, hash-verified

200/// (person.id, person.age, person.state, person.birth_date)\
201/// )
202pub 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.

Callers 2

try_newMethod · 0.85

Calls 10

powersetFunction · 0.85
cross_join_grouping_setsFunction · 0.85
collectMethod · 0.80
anyMethod · 0.45
iterMethod · 0.45
lenMethod · 0.45
mapMethod · 0.45
into_iterMethod · 0.45
clonedMethod · 0.45

Tested by 1

Used in the wild real call sites across dependent graphs

searching dependent graphs…