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

Method remove_undemanded

src/expr/src/linear.rs:1383–1433  ·  view source on GitHub ↗

Removes unused expressions from `self.expressions`. Expressions are "used" if they are relied upon by any output columns or any predicates, even transitively. Any expressions that are not relied upon in this way can be discarded. # Example ```rust use mz_expr::{func, MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc}; // Use the output from `inline_expression` example. let mut map_filter_p

(&mut self)

Source from the content-addressed store, hash-verified

1381 /// );
1382 /// ```
1383 pub fn remove_undemanded(&mut self) {
1384 // Determine the demanded expressions to remove irrelevant ones.
1385 let mut demand = BTreeSet::new();
1386 for (_index, pred) in self.predicates.iter() {
1387 demand.extend(pred.support());
1388 }
1389 // Start from the output columns as presumed demanded.
1390 // If this is not the case, the caller should project some away.
1391 demand.extend(self.projection.iter().cloned());
1392 // Proceed in *reverse* order, as expressions may depend on other
1393 // expressions that precede them.
1394 for index in (0..self.expressions.len()).rev() {
1395 if demand.contains(&(self.input_arity + index)) {
1396 demand.extend(self.expressions[index].support());
1397 }
1398 }
1399
1400 // Maintain a map from initial column identifiers to locations
1401 // once we have removed undemanded expressions.
1402 let mut remap = BTreeMap::new();
1403 // This map only needs to map elements of `demand` to a new location,
1404 // but the logic is easier if we include all input columns (as the
1405 // new position is then determined by the size of the map).
1406 for index in 0..self.input_arity {
1407 remap.insert(index, index);
1408 }
1409 // Retain demanded expressions, and record their new locations.
1410 let mut new_expressions = Vec::new();
1411 for (index, expr) in self.expressions.drain(..).enumerate() {
1412 if demand.contains(&(index + self.input_arity)) {
1413 remap.insert(index + self.input_arity, remap.len());
1414 new_expressions.push(expr);
1415 }
1416 }
1417 self.expressions = new_expressions;
1418
1419 // Update column identifiers; rebuild `Self` to re-establish any invariants.
1420 // We mirror `self.permute(&remap)` but we specifically want to remap columns
1421 // that are produced by `self.expressions` after the input columns.
1422 let (expressions, predicates, projection) = self.as_map_filter_project();
1423 *self = Self::new(self.input_arity)
1424 .map(expressions.into_iter().map(|mut e| {
1425 e.permute_map(&remap);
1426 e
1427 }))
1428 .filter(predicates.into_iter().map(|mut p| {
1429 p.permute_map(&remap);
1430 p
1431 }))
1432 .project(projection.into_iter().map(|c| remap[&c]));
1433 }
1434}
1435
1436// TODO: move this elsewhere?

Callers 1

optimizeMethod · 0.80

Calls 15

enumerateMethod · 0.80
as_map_filter_projectMethod · 0.80
permute_mapMethod · 0.80
iterMethod · 0.45
extendMethod · 0.45
supportMethod · 0.45
lenMethod · 0.45
containsMethod · 0.45
insertMethod · 0.45
drainMethod · 0.45
pushMethod · 0.45
projectMethod · 0.45

Tested by

no test coverage detected