Pushes Reduce operators toward sources. A join can be thought of as a multigraph where vertices are inputs and edges are join constraints. After removing constraints containing a GroupBy, the reduce will be pushed down to all connected components. If there is only one connected component, this method is a no-op.
(&self, relation: &mut MirRelationExpr)
| 91 | /// GroupBy, the reduce will be pushed down to all connected components. If |
| 92 | /// there is only one connected component, this method is a no-op. |
| 93 | pub fn action(&self, relation: &mut MirRelationExpr) { |
| 94 | if let MirRelationExpr::Reduce { |
| 95 | input, |
| 96 | group_key, |
| 97 | aggregates, |
| 98 | monotonic, |
| 99 | expected_group_size, |
| 100 | } = relation |
| 101 | { |
| 102 | // Map expressions can be absorbed into the Reduce at no cost. |
| 103 | if let MirRelationExpr::Map { |
| 104 | input: inner, |
| 105 | scalars, |
| 106 | } = &mut **input |
| 107 | { |
| 108 | let arity = inner.arity(); |
| 109 | |
| 110 | // Normalize the scalars to not be self-referential. |
| 111 | let mut scalars = scalars.clone(); |
| 112 | for index in 0..scalars.len() { |
| 113 | let (lower, upper) = scalars.split_at_mut(index); |
| 114 | upper[0].visit_mut_post(&mut |e| { |
| 115 | if let mz_expr::MirScalarExpr::Column(c, _) = e { |
| 116 | if *c >= arity { |
| 117 | *e = lower[*c - arity].clone(); |
| 118 | } |
| 119 | } |
| 120 | }); |
| 121 | } |
| 122 | for key in group_key.iter_mut() { |
| 123 | key.visit_mut_post(&mut |e| { |
| 124 | if let mz_expr::MirScalarExpr::Column(c, _) = e { |
| 125 | if *c >= arity { |
| 126 | *e = scalars[*c - arity].clone(); |
| 127 | } |
| 128 | } |
| 129 | }); |
| 130 | } |
| 131 | for agg in aggregates.iter_mut() { |
| 132 | agg.expr.visit_mut_post(&mut |e| { |
| 133 | if let mz_expr::MirScalarExpr::Column(c, _) = e { |
| 134 | if *c >= arity { |
| 135 | *e = scalars[*c - arity].clone(); |
| 136 | } |
| 137 | } |
| 138 | }); |
| 139 | } |
| 140 | |
| 141 | **input = inner.take_dangerous() |
| 142 | } |
| 143 | if let MirRelationExpr::Join { |
| 144 | inputs, |
| 145 | equivalences, |
| 146 | implementation: _, |
| 147 | } = &mut **input |
| 148 | { |
| 149 | if let Some(new_relation_expr) = try_push_reduce_through_join( |
| 150 | inputs, |
no test coverage detected