mz_transform/
monotonic.rs1use std::collections::BTreeSet;
13
14use mz_expr::MirRelationExpr;
15use mz_repr::GlobalId;
16
17use crate::TransformCtx;
18use crate::analysis::DerivedBuilder;
19use crate::analysis::monotonic::Monotonic;
20
21#[derive(Debug, Default)]
23pub struct MonotonicFlag;
24
25impl MonotonicFlag {
26 pub fn transform(
29 &self,
30 expr: &mut MirRelationExpr,
31 ctx: &mut TransformCtx,
32 global_monotonic_ids: &BTreeSet<GlobalId>,
33 ) -> Result<(), crate::RecursionLimitError> {
34 let mut builder = DerivedBuilder::new(ctx.features);
35 builder.require(Monotonic::new(global_monotonic_ids.clone()));
36 let derived = builder.visit(&*expr);
37
38 let mut todo = vec![(&mut *expr, derived.as_view())];
39 while let Some((expr, view)) = todo.pop() {
40 match expr {
41 MirRelationExpr::Reduce { monotonic, .. }
42 | MirRelationExpr::TopK { monotonic, .. } => {
43 *monotonic = *view
44 .last_child()
45 .value::<Monotonic>()
46 .expect("Monotonic required");
47 }
48 _ => {}
49 }
50 todo.extend(expr.children_mut().rev().zip(view.children_rev()))
51 }
52
53 mz_repr::explain::trace_plan(&*expr);
54 Ok(())
55 }
56}