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

Function install_lifted_mfp

src/transform/src/join_implementation.rs:943–990  ·  view source on GitHub ↗

This function continues the surgery that `implement_arrangements` started. (In theory, this function could be merged into `implement_arrangements`, but it would be a bit painful, because we need to access the join's `implementation` after `implement_arrangements`, which would be somewhat convoluted after what `install_lifted_mfp` does.) The given MFP should be the merged MFP from all the lifted

(new_join: &mut MirRelationExpr, mfp: MapFilterProject)

Source from the content-addressed store, hash-verified

941/// - Canonicalizes scalar expressions in maps and filters with respect to the join equivalences.
942/// See inline comment for more details.
943fn install_lifted_mfp(new_join: &mut MirRelationExpr, mfp: MapFilterProject) {
944 if !mfp.is_identity() {
945 let (mut map, mut filter, project) = mfp.as_map_filter_project();
946 if let MirRelationExpr::Join { equivalences, .. } = new_join {
947 for equivalence in equivalences.iter_mut() {
948 for expr in equivalence.iter_mut() {
949 // permute `equivalences` in light of the project being lifted
950 expr.permute(&project);
951 // if column references refer to mapped expressions that have been
952 // lifted, replace the column reference with the mapped expression.
953 expr.visit_mut_pre(&mut |e| {
954 // This has to be a loop! This is because it can happen that the new
955 // expression is again a column reference, in which case the visitor
956 // wouldn't be called on it again. (The visitation continues with the
957 // children of the new expression, but won't visit the new expression
958 // itself again.)
959 while let MirScalarExpr::Column(c, _) = e {
960 if *c >= mfp.input_arity {
961 *e = map[*c - mfp.input_arity].clone();
962 } else {
963 break;
964 }
965 }
966 });
967 }
968 }
969 // Canonicalize scalar expressions in maps and filters with respect to the join
970 // equivalences. This often makes some filters identical, which are then removed.
971 // The identical filters come from either
972 // - lifting several predicates that originally were pushed down by localizing to more
973 // than one inputs;
974 // - individual IS NOT NULL filters on each of the inputs, which become identical
975 // when rewritten using the join equivalences.
976 // (This allows for almost the same optimizations as when `Demand`
977 // used to insert Projections that were marking some columns to be
978 // identical, when Demand used to run after `JoinImplementation`.)
979 let canonicalizer_map = mz_expr::canonicalize::get_canonicalizer_map(equivalences);
980 for expr in map.iter_mut().chain(filter.iter_mut()) {
981 expr.visit_mut_post(&mut |e| {
982 if let Some(canonical_expr) = canonicalizer_map.get(e) {
983 *e = canonical_expr.clone();
984 }
985 })
986 }
987 }
988 *new_join = new_join.clone().map(map).filter(filter).project(project);
989 }
990}
991
992/// Permute the keys in `order` to compensate for projections being lifted from inputs.
993/// `lifted_projections` has an optional projection for each input.

Callers 1

planFunction · 0.85

Calls 11

get_canonicalizer_mapFunction · 0.85
as_map_filter_projectMethod · 0.80
visit_mut_preMethod · 0.80
visit_mut_postMethod · 0.80
is_identityMethod · 0.45
permuteMethod · 0.45
cloneMethod · 0.45
getMethod · 0.45
projectMethod · 0.45
filterMethod · 0.45
mapMethod · 0.45

Tested by

no test coverage detected