This function associates stable node indices with [`PhysicalExpr`]s so that we can match `Arc ` and NodeIndex objects during membership tests.
(
&mut self,
exprs: &[Arc<dyn PhysicalExpr>],
)
| 455 | /// that we can match `Arc<dyn PhysicalExpr>` and NodeIndex objects during |
| 456 | /// membership tests. |
| 457 | pub fn gather_node_indices( |
| 458 | &mut self, |
| 459 | exprs: &[Arc<dyn PhysicalExpr>], |
| 460 | ) -> Vec<(Arc<dyn PhysicalExpr>, usize)> { |
| 461 | let graph = &self.graph; |
| 462 | let mut bfs = Bfs::new(graph, self.root); |
| 463 | // We collect the node indices (usize) of [PhysicalExpr]s in the order |
| 464 | // given by argument `exprs`. To preserve this order, we initialize each |
| 465 | // expression's node index with usize::MAX, and then find the corresponding |
| 466 | // node indices by traversing the graph. |
| 467 | let mut removals = vec![]; |
| 468 | let mut expr_node_indices = exprs |
| 469 | .iter() |
| 470 | .map(|e| (Arc::clone(e), usize::MAX)) |
| 471 | .collect::<Vec<_>>(); |
| 472 | while let Some(node) = bfs.next(graph) { |
| 473 | // Get the plan corresponding to this node: |
| 474 | let expr = &graph[node].expr; |
| 475 | // If the current expression is among `exprs`, slate its children |
| 476 | // for removal: |
| 477 | if let Some(value) = exprs.iter().position(|e| expr.eq(e)) { |
| 478 | // Update the node index of the associated `PhysicalExpr`: |
| 479 | expr_node_indices[value].1 = node.index(); |
| 480 | for edge in graph.edges_directed(node, Outgoing) { |
| 481 | // Slate the child for removal, do not remove immediately. |
| 482 | removals.push(edge.id()); |
| 483 | } |
| 484 | } |
| 485 | } |
| 486 | for edge_idx in removals { |
| 487 | self.graph.remove_edge(edge_idx); |
| 488 | } |
| 489 | // Get the set of node indices reachable from the root node: |
| 490 | let connected_nodes = self.connected_nodes(); |
| 491 | // Remove nodes not connected to the root node: |
| 492 | self.graph |
| 493 | .retain_nodes(|_, index| connected_nodes.contains(&index)); |
| 494 | expr_node_indices |
| 495 | } |
| 496 | |
| 497 | /// Returns the set of node indices reachable from the root node via a |
| 498 | /// simple depth-first search. |