MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / action

Method action

src/transform/src/join_implementation.rs:130–526  ·  view source on GitHub ↗

Determines the join implementation for join operators.

(
        &self,
        relation: &mut MirRelationExpr,
        mfp_above: MapFilterProject,
        indexes: &IndexMap,
        stats: &dyn StatisticsOracle,
        features: &OptimizerFeatures,
  

Source from the content-addressed store, hash-verified

128
129 /// Determines the join implementation for join operators.
130 pub fn action(
131 &self,
132 relation: &mut MirRelationExpr,
133 mfp_above: MapFilterProject,
134 indexes: &IndexMap,
135 stats: &dyn StatisticsOracle,
136 features: &OptimizerFeatures,
137 ) -> Result<(), TransformError> {
138 if let MirRelationExpr::Join {
139 inputs,
140 equivalences,
141 // (Note that `JoinImplementation` runs in a fixpoint loop.)
142 // If the current implementation is
143 // - Unimplemented, then we need to come up with an implementation.
144 // - Differential, then we consider switching to a Delta join, because we might have
145 // inserted some ArrangeBys that create new arrangements when we came up with the
146 // Differential plan, in which case a Delta join might have become viable.
147 // - Delta, then we are good already.
148 // - IndexedFilter, then we just leave that alone, because those are out of scope
149 // for JoinImplementation (they are created by `LiteralConstraints`).
150 // We don't want to change from a Differential plan to an other Differential plan, or
151 // from a Delta plan to an other Delta plan, because the second run cannot distinguish
152 // between an ArrangeBy that marks an already existing arrangement and an ArrangeBy
153 // that was inserted by a previous run of JoinImplementation. (We should eventually
154 // refactor this to make ArrangeBy unambiguous somehow. Maybe move JoinImplementation
155 // to the lowering.)
156 implementation: implementation @ (Unimplemented | Differential(..)),
157 } = relation
158 {
159 // If we eagerly plan delta joins, we don't need the second run to "pick up" delta joins
160 // that could be planned with the arrangements from a differential. If such a delta
161 // join were viable, we'd have already planned it the first time.
162 if features.enable_eager_delta_joins && !matches!(implementation, Unimplemented) {
163 return Ok(());
164 }
165
166 let input_types = inputs.iter().map(|i| i.typ()).collect::<Vec<_>>();
167
168 // Canonicalize the equivalence classes
169 if matches!(implementation, Unimplemented) {
170 // Let's do this only if it's the first run of JoinImplementation, in which case we
171 // are guaranteed to produce a new plan, which will be compatible with the modified
172 // equivalences from the below call. Otherwise, if we already have a Differential or
173 // a Delta join, then we might discard the new plan and go with the old plan, which
174 // was created previously for the old equivalences, and might be invalid for the
175 // modified equivalences from the below call. Note that this issue can arise only if
176 // `canonicalize_equivalences` is not idempotent, which unfortunately seems to be
177 // the case.
178 mz_expr::canonicalize::canonicalize_equivalences(
179 equivalences,
180 input_types.iter().map(|t| &t.column_types),
181 );
182 }
183
184 // Common information of broad utility.
185 let input_mapper = JoinInputMapper::new_from_input_types(&input_types);
186
187 // The first fundamental question is whether we should employ a delta query or not.

Callers 1

action_recursiveMethod · 0.45

Calls 15

as_map_filter_projectMethod · 0.80
allMethod · 0.80
add_literal_equalityMethod · 0.80
unwrapMethod · 0.80
as_viewMethod · 0.80
roundedMethod · 0.80
to_vecMethod · 0.80
sortMethod · 0.80
enumerateMethod · 0.80
contains_keyMethod · 0.80

Tested by

no test coverage detected