(
env: &mut Environment,
statement: &GroupByStatement,
gitql_object: &mut GitQLObject,
)
| 13 | use crate::engine_evaluator::evaluate_expression; |
| 14 | |
| 15 | pub(crate) fn execute_group_by_statement( |
| 16 | env: &mut Environment, |
| 17 | statement: &GroupByStatement, |
| 18 | gitql_object: &mut GitQLObject, |
| 19 | ) -> Result<(), String> { |
| 20 | if gitql_object.is_empty() { |
| 21 | return Ok(()); |
| 22 | } |
| 23 | |
| 24 | let main_group = gitql_object.groups.remove(0); |
| 25 | if main_group.is_empty() { |
| 26 | return Ok(()); |
| 27 | } |
| 28 | |
| 29 | // Mapping each unique value to it group index |
| 30 | let mut groups_map: HashMap<u64, usize> = HashMap::new(); |
| 31 | |
| 32 | // Track current group index |
| 33 | let mut next_group_index = 0; |
| 34 | let values_count = statement.values.len(); |
| 35 | |
| 36 | let is_roll_up_enabled = statement.has_with_roll_up; |
| 37 | let indexes_combinations = if is_roll_up_enabled { |
| 38 | generate_list_of_all_combinations(values_count) |
| 39 | } else { |
| 40 | vec![(0..values_count).collect()] |
| 41 | }; |
| 42 | |
| 43 | // For each row should check the group by values combinations to build multi groups |
| 44 | for row in main_group.rows.iter() { |
| 45 | // Create all combination of values for each row |
| 46 | for indexes in indexes_combinations.iter() { |
| 47 | let mut row_values: Vec<String> = Vec::with_capacity(indexes.len()); |
| 48 | for index in indexes { |
| 49 | let value = evaluate_expression( |
| 50 | env, |
| 51 | &statement.values[*index], |
| 52 | &gitql_object.titles, |
| 53 | &row.values, |
| 54 | )?; |
| 55 | row_values.push(value.literal()); |
| 56 | } |
| 57 | |
| 58 | // Compute the hash for row of values |
| 59 | let mut hasher = DefaultHasher::new(); |
| 60 | row_values.hash(&mut hasher); |
| 61 | let values_hash = hasher.finish(); |
| 62 | |
| 63 | // Push a new group for this unique value and update the next index |
| 64 | if let Vacant(e) = groups_map.entry(values_hash) { |
| 65 | e.insert(next_group_index); |
| 66 | next_group_index += 1; |
| 67 | gitql_object.groups.push(Group { |
| 68 | rows: vec![row.clone()], |
| 69 | }); |
| 70 | continue; |
| 71 | } |
| 72 |
no test coverage detected
searching dependent graphs…