Prepares the last sorting that will be appended to the pipeline of the `SqlQuery` by `fold_sql_query`. It does so by reverting all columns in the sorting to their very first form, and then transforming their value in the final select, while applying renaming/aliasing when possible. This cannot be done directly in `fold_sql_transforms` because renames are not considered to be SQL transforms.
(&mut self, mut last_sorting: Sorting, final_select: &[CId])
| 57 | /// renaming/aliasing when possible. This cannot be done directly in `fold_sql_transforms` |
| 58 | /// because renames are not considered to be SQL transforms. |
| 59 | fn alias_last_sorting(&mut self, mut last_sorting: Sorting, final_select: &[CId]) -> Sorting { |
| 60 | log::debug!("unaliasing last sorting: {last_sorting:?}"); |
| 61 | let redirects = self |
| 62 | .ctx |
| 63 | .anchor |
| 64 | .relation_instances |
| 65 | .iter() |
| 66 | .map(|(riid, rel_inst)| (riid, &rel_inst.cid_redirects)) |
| 67 | .collect::<HashMap<_, _>>(); |
| 68 | |
| 69 | // a map of column -> alias |
| 70 | let column_aliases = self |
| 71 | .ctx |
| 72 | .anchor |
| 73 | .column_decls |
| 74 | .values() |
| 75 | .filter_map(|col| { |
| 76 | if let ColumnDecl::Compute(compute) = col { |
| 77 | if let ExprKind::ColumnRef(referenced_id) = compute.expr.kind { |
| 78 | Some((referenced_id, compute.id)) |
| 79 | } else { |
| 80 | None |
| 81 | } |
| 82 | } else { |
| 83 | None |
| 84 | } |
| 85 | }) |
| 86 | .collect::<HashMap<_, _>>(); |
| 87 | log::debug!(".. column aliases: {column_aliases:?}"); |
| 88 | |
| 89 | // column -> list of tables that did a revert |
| 90 | let mut reverts: HashMap<CId, VecDeque<RIId>> = HashMap::new(); |
| 91 | log::debug!(".. reverting all columns to their original value"); |
| 92 | last_sorting.iter_mut().for_each(|sort| { |
| 93 | let mut riids = VecDeque::new(); |
| 94 | let mut changed = true; |
| 95 | while changed { |
| 96 | changed = false; |
| 97 | if let Some(ColumnDecl::RelationColumn(riid, cid, _)) = |
| 98 | self.ctx.anchor.column_decls.get(&sort.column) |
| 99 | { |
| 100 | let cid_redirects = redirects[riid]; |
| 101 | for (source, target) in cid_redirects.iter() { |
| 102 | if target == cid { |
| 103 | log::debug!( |
| 104 | ".. reverting {target:?} back to {source:?} via redirects of {riid:?}" |
| 105 | ); |
| 106 | sort.column = *source; |
| 107 | changed = true; |
| 108 | riids.push_front(*riid); |
| 109 | break; |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | reverts.insert(sort.column, riids); |
| 115 | }); |
| 116 | log::debug!(".. done reverting all columns to their original value: {last_sorting:?}"); |
no test coverage detected