Calculates the statistics after applying `fetch` and `skip` operations. Here, `self` denotes per-partition statistics. Use the `n_partitions` parameter to compute global statistics in a multi-partition setting.
(
mut self,
fetch: Option<usize>,
skip: usize,
n_partitions: usize,
)
| 534 | /// Here, `self` denotes per-partition statistics. Use the `n_partitions` |
| 535 | /// parameter to compute global statistics in a multi-partition setting. |
| 536 | pub fn with_fetch( |
| 537 | mut self, |
| 538 | fetch: Option<usize>, |
| 539 | skip: usize, |
| 540 | n_partitions: usize, |
| 541 | ) -> Result<Self> { |
| 542 | let fetch_val = fetch.unwrap_or(usize::MAX); |
| 543 | |
| 544 | // Get the ratio of rows after / rows before on a per-partition basis |
| 545 | let num_rows_before = self.num_rows; |
| 546 | |
| 547 | self.num_rows = match self { |
| 548 | Statistics { |
| 549 | num_rows: Precision::Exact(nr), |
| 550 | .. |
| 551 | } |
| 552 | | Statistics { |
| 553 | num_rows: Precision::Inexact(nr), |
| 554 | .. |
| 555 | } => { |
| 556 | // Here, the inexact case gives us an estimate of the number of rows. |
| 557 | if nr <= skip { |
| 558 | // All input data will be skipped. Preserve the exactness of |
| 559 | // the input estimate: if the input was inexact, the |
| 560 | // resulting zero is also inexact. |
| 561 | check_num_rows(Some(0), self.num_rows.is_exact().unwrap()) |
| 562 | } else if nr <= fetch_val && skip == 0 { |
| 563 | // If the input does not reach the `fetch` globally, and `skip` |
| 564 | // is zero (meaning the input and output are identical), return |
| 565 | // input stats as is. |
| 566 | // TODO: Can input stats still be used, but adjusted, when `skip` |
| 567 | // is non-zero? |
| 568 | return Ok(self); |
| 569 | } else if nr - skip <= fetch_val { |
| 570 | // After `skip` input rows are skipped, the remaining rows are |
| 571 | // less than or equal to the `fetch` values, so `num_rows` must |
| 572 | // equal the remaining rows. |
| 573 | check_num_rows( |
| 574 | (nr - skip).checked_mul(n_partitions), |
| 575 | // We know that we have an estimate for the number of rows: |
| 576 | self.num_rows.is_exact().unwrap(), |
| 577 | ) |
| 578 | } else { |
| 579 | // At this point we know that we were given a `fetch` value |
| 580 | // as the `None` case would go into the branch above. Since |
| 581 | // the input has more rows than `fetch + skip`, the number |
| 582 | // of rows will be the `fetch`, other statistics will have to be downgraded to inexact. |
| 583 | check_num_rows( |
| 584 | fetch_val.checked_mul(n_partitions), |
| 585 | // We know that we have an estimate for the number of rows: |
| 586 | self.num_rows.is_exact().unwrap(), |
| 587 | ) |
| 588 | } |
| 589 | } |
| 590 | Statistics { |
| 591 | num_rows: Precision::Absent, |
| 592 | .. |
| 593 | } => check_num_rows(fetch.and_then(|v| v.checked_mul(n_partitions)), false), |