| 179 | /// This requires rewriting all correlated subqueries (nested `HirRelationExpr`s) into flat queries |
| 180 | #[mz_ore::instrument(target = "optimizer", level = "trace", name = "hir_to_mir")] |
| 181 | pub fn lower<C: Into<Config>>( |
| 182 | self, |
| 183 | config: C, |
| 184 | metrics: Option<&OptimizerMetrics>, |
| 185 | ) -> Result<MirRelationExpr, PlanError> { |
| 186 | let context = Context { |
| 187 | config: &config.into(), |
| 188 | metrics, |
| 189 | }; |
| 190 | let result = match self { |
| 191 | // We directly rewrite a Constant into the corresponding `MirRelationExpr::Constant` |
| 192 | // to ensure that the downstream optimizer can easily bypass most |
| 193 | // irrelevant optimizations (e.g. reduce folding) for this expression |
| 194 | // without having to re-learn the fact that it is just a constant, |
| 195 | // as it would if the constant were wrapped in a Let-Get pair. |
| 196 | HirRelationExpr::Constant { rows, typ } => { |
| 197 | let rows: Vec<_> = rows.into_iter().map(|row| (row, Diff::ONE)).collect(); |
| 198 | MirRelationExpr::Constant { |
| 199 | rows: Ok(rows), |
| 200 | typ: ReprRelationType::from(&typ), |
| 201 | } |
| 202 | } |
| 203 | mut other => { |
| 204 | let mut id_gen = mz_ore::id_gen::IdGen::default(); |
| 205 | transform_hir::split_subquery_predicates(&mut other)?; |
| 206 | transform_hir::try_simplify_quantified_comparisons( |
| 207 | &mut other, |
| 208 | context.config.enable_simplify_quantified_comparisons, |
| 209 | )?; |
| 210 | transform_hir::fuse_window_functions(&mut other, &context)?; |
| 211 | MirRelationExpr::constant(vec![vec![]], ReprRelationType::new(vec![])).let_in( |
| 212 | &mut id_gen, |
| 213 | |id_gen, get_outer| { |
| 214 | other.applied_to( |
| 215 | id_gen, |
| 216 | get_outer, |
| 217 | &ColumnMap::empty(), |
| 218 | &mut CteMap::new(), |
| 219 | &context, |
| 220 | ) |
| 221 | }, |
| 222 | )? |
| 223 | } |
| 224 | }; |
| 225 | |
| 226 | mz_repr::explain::trace_plan(&result); |
| 227 | |
| 228 | Ok(result) |
| 229 | } |
| 230 | |
| 231 | /// Return a `MirRelationExpr` which evaluates `self` once for each row of `get_outer`. |
| 232 | /// |