(&self, array: &ArrayRef, range: &Range<usize>)
| 475 | |
| 476 | impl NthValueEvaluator { |
| 477 | fn valid_index(&self, array: &ArrayRef, range: &Range<usize>) -> Option<usize> { |
| 478 | let n_range = range.end - range.start; |
| 479 | if self.ignore_nulls { |
| 480 | // Calculate valid indices, inside the window frame boundaries. |
| 481 | let slice = array.slice(range.start, n_range); |
| 482 | if let Some(nulls) = slice.nulls() |
| 483 | && nulls.null_count() > 0 |
| 484 | { |
| 485 | return self.valid_index_with_nulls(nulls, range.start); |
| 486 | } |
| 487 | } |
| 488 | // Either no nulls, or nulls are regarded as valid rows |
| 489 | match self.state.kind { |
| 490 | NthValueKind::First => Some(range.start), |
| 491 | NthValueKind::Last => Some(range.end - 1), |
| 492 | NthValueKind::Nth => match self.n.cmp(&0) { |
| 493 | Ordering::Greater => { |
| 494 | // SQL indices are not 0-based. |
| 495 | let index = (self.n as usize) - 1; |
| 496 | if index >= n_range { |
| 497 | // Outside the range, return NULL: |
| 498 | None |
| 499 | } else { |
| 500 | Some(range.start + index) |
| 501 | } |
| 502 | } |
| 503 | Ordering::Less => { |
| 504 | let reverse_index = (-self.n) as usize; |
| 505 | if n_range < reverse_index { |
| 506 | // Outside the range, return NULL: |
| 507 | None |
| 508 | } else { |
| 509 | Some(range.end - reverse_index) |
| 510 | } |
| 511 | } |
| 512 | Ordering::Equal => None, |
| 513 | }, |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | fn valid_index_with_nulls(&self, nulls: &NullBuffer, offset: usize) -> Option<usize> { |
| 518 | match self.state.kind { |
no test coverage detected