Implementation for [`RowSetFinishing::finish`].
(
&self,
rows: RowCollection,
max_result_size: u64,
max_returned_query_size: Option<u64>,
)
| 3606 | |
| 3607 | /// Implementation for [`RowSetFinishing::finish`]. |
| 3608 | fn finish_inner( |
| 3609 | &self, |
| 3610 | rows: RowCollection, |
| 3611 | max_result_size: u64, |
| 3612 | max_returned_query_size: Option<u64>, |
| 3613 | ) -> Result<(RowCollectionIter, usize), String> { |
| 3614 | // How much additional memory is required to make a sorted view. |
| 3615 | let sorted_view_mem = rows.entries().saturating_mul(std::mem::size_of::<usize>()); |
| 3616 | let required_memory = rows.byte_len().saturating_add(sorted_view_mem); |
| 3617 | |
| 3618 | // Bail if creating the sorted view would require us to use too much memory. |
| 3619 | if required_memory > usize::cast_from(max_result_size) { |
| 3620 | let max_bytes = ByteSize::b(max_result_size); |
| 3621 | return Err(format!("result exceeds max size of {max_bytes}",)); |
| 3622 | } |
| 3623 | |
| 3624 | let sorted_view = rows; |
| 3625 | let mut iter = sorted_view |
| 3626 | .into_row_iter() |
| 3627 | .apply_offset(self.offset) |
| 3628 | .with_projection(self.project.clone()); |
| 3629 | |
| 3630 | if let Some(limit) = self.limit { |
| 3631 | let limit = u64::from(limit); |
| 3632 | let limit = usize::cast_from(limit); |
| 3633 | iter = iter.with_limit(limit); |
| 3634 | }; |
| 3635 | |
| 3636 | // TODO(parkmycar): Re-think how we can calculate the total response size without |
| 3637 | // having to iterate through the entire collection of Rows, while still |
| 3638 | // respecting the LIMIT, OFFSET, and projections. |
| 3639 | // |
| 3640 | // Note: It feels a bit bad always calculating the response size, but we almost |
| 3641 | // always need it to either check the `max_returned_query_size`, or for reporting |
| 3642 | // in the query history. |
| 3643 | let response_size: usize = iter.clone().map(|row| row.data().len()).sum(); |
| 3644 | |
| 3645 | // Bail if we would end up returning more data to the client than they can support. |
| 3646 | if let Some(max) = max_returned_query_size { |
| 3647 | if response_size > usize::cast_from(max) { |
| 3648 | let max_bytes = ByteSize::b(max); |
| 3649 | return Err(format!("result exceeds max size of {max_bytes}")); |
| 3650 | } |
| 3651 | } |
| 3652 | |
| 3653 | Ok((iter, response_size)) |
| 3654 | } |
| 3655 | } |
| 3656 | |
| 3657 | /// A [RowSetFinishing] that can be repeatedly applied to batches of updates (in |
no test coverage detected