Extracts temporal predicates into their own `Self`. Expressions that are used by the temporal predicates are exposed by `self.projection`, though there could be justification for extracting them as well if they are otherwise unused. This separation is valuable when the execution cannot be fused into one operator.
(&mut self)
| 416 | /// |
| 417 | /// This separation is valuable when the execution cannot be fused into one operator. |
| 418 | pub fn extract_temporal(&mut self) -> Self { |
| 419 | // Optimize the expression, as it is only post-optimization that we can be certain |
| 420 | // that temporal expressions are restricted to filters. We could relax this in the |
| 421 | // future to be only `inline_expressions` and `remove_undemanded`, but optimization |
| 422 | // seems to be the best fit at the moment. |
| 423 | self.optimize(); |
| 424 | |
| 425 | // Assert that we no longer have temporal expressions to evaluate. This should only |
| 426 | // occur if the optimization above results with temporal expressions yielded in the |
| 427 | // output, which is out of spec for how the type is meant to be used. |
| 428 | assert!( |
| 429 | !self |
| 430 | .expressions |
| 431 | .iter() |
| 432 | .any(|e| OptimizableExpr::contains_temporal(e)) |
| 433 | ); |
| 434 | |
| 435 | // Extract temporal predicates from `self.predicates`. |
| 436 | let mut temporal_predicates = Vec::new(); |
| 437 | self.predicates.retain(|(_position, predicate)| { |
| 438 | if OptimizableExpr::contains_temporal(predicate) { |
| 439 | temporal_predicates.push(predicate.clone()); |
| 440 | false |
| 441 | } else { |
| 442 | true |
| 443 | } |
| 444 | }); |
| 445 | |
| 446 | // Determine extended input columns used by temporal filters. |
| 447 | let mut support = BTreeSet::new(); |
| 448 | for predicate in temporal_predicates.iter() { |
| 449 | support.extend(predicate.support()); |
| 450 | } |
| 451 | |
| 452 | // Discover the locations of these columns after `self.projection`. |
| 453 | let old_projection_len = self.projection.len(); |
| 454 | let mut new_location = BTreeMap::new(); |
| 455 | for original in support.iter() { |
| 456 | if let Some(position) = self.projection.iter().position(|x| x == original) { |
| 457 | new_location.insert(*original, position); |
| 458 | } else { |
| 459 | new_location.insert(*original, self.projection.len()); |
| 460 | self.projection.push(*original); |
| 461 | } |
| 462 | } |
| 463 | // Permute references in extracted predicates to their new locations. |
| 464 | for predicate in temporal_predicates.iter_mut() { |
| 465 | predicate.permute_map(&new_location); |
| 466 | } |
| 467 | |
| 468 | // Form a new `Self` containing the temporal predicates to return. |
| 469 | Self::new(self.projection.len()) |
| 470 | .filter(temporal_predicates) |
| 471 | .project(0..old_projection_len) |
| 472 | } |
| 473 | |
| 474 | /// Extracts common expressions from multiple `Self` into a result `Self`. |
| 475 | /// |