(datums: Vec<Datum<'a>>, window_frame: &WindowFrame)
| 953 | } |
| 954 | |
| 955 | fn first_value_inner<'a>(datums: Vec<Datum<'a>>, window_frame: &WindowFrame) -> Vec<Datum<'a>> { |
| 956 | let length = datums.len(); |
| 957 | let mut result: Vec<Datum> = Vec::with_capacity(length); |
| 958 | for (idx, current_datum) in datums.iter().enumerate() { |
| 959 | let first_value = match &window_frame.start_bound { |
| 960 | // Always return the current value |
| 961 | WindowFrameBound::CurrentRow => *current_datum, |
| 962 | WindowFrameBound::UnboundedPreceding => { |
| 963 | if let WindowFrameBound::OffsetPreceding(end_offset) = &window_frame.end_bound { |
| 964 | let end_offset = usize::cast_from(*end_offset); |
| 965 | |
| 966 | // If the frame ends before the first row, return null |
| 967 | if idx < end_offset { |
| 968 | Datum::Null |
| 969 | } else { |
| 970 | datums[0] |
| 971 | } |
| 972 | } else { |
| 973 | datums[0] |
| 974 | } |
| 975 | } |
| 976 | WindowFrameBound::OffsetPreceding(offset) => { |
| 977 | let start_offset = usize::cast_from(*offset); |
| 978 | let start_idx = idx.saturating_sub(start_offset); |
| 979 | if let WindowFrameBound::OffsetPreceding(end_offset) = &window_frame.end_bound { |
| 980 | let end_offset = usize::cast_from(*end_offset); |
| 981 | |
| 982 | // If the frame is empty or ends before the first row, return null |
| 983 | if start_offset < end_offset || idx < end_offset { |
| 984 | Datum::Null |
| 985 | } else { |
| 986 | datums[start_idx] |
| 987 | } |
| 988 | } else { |
| 989 | datums[start_idx] |
| 990 | } |
| 991 | } |
| 992 | WindowFrameBound::OffsetFollowing(offset) => { |
| 993 | let start_offset = usize::cast_from(*offset); |
| 994 | let start_idx = idx.saturating_add(start_offset); |
| 995 | if let WindowFrameBound::OffsetFollowing(end_offset) = &window_frame.end_bound { |
| 996 | // If the frame is empty or starts after the last row, return null |
| 997 | if offset > end_offset || start_idx >= length { |
| 998 | Datum::Null |
| 999 | } else { |
| 1000 | datums[start_idx] |
| 1001 | } |
| 1002 | } else { |
| 1003 | datums |
| 1004 | .get(start_idx) |
| 1005 | .map(|d| d.clone()) |
| 1006 | .unwrap_or(Datum::Null) |
| 1007 | } |
| 1008 | } |
| 1009 | // Forbidden during planning |
| 1010 | WindowFrameBound::UnboundedFollowing => unreachable!(), |
| 1011 | }; |
| 1012 | result.push(first_value); |
no test coverage detected