proof_of_sql/sql/postprocessing/
slice_postprocessing.rsuse super::{PostprocessingError, PostprocessingResult, PostprocessingStep};
use crate::base::{database::OwnedTable, scalar::Scalar};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SlicePostprocessing {
number_rows: Option<u64>,
offset_value: Option<i64>,
}
impl SlicePostprocessing {
#[must_use]
pub fn new(number_rows: Option<u64>, offset_value: Option<i64>) -> Self {
Self {
number_rows,
offset_value,
}
}
}
impl<S: Scalar> PostprocessingStep<S> for SlicePostprocessing {
fn apply(&self, owned_table: OwnedTable<S>) -> PostprocessingResult<OwnedTable<S>> {
let num_rows = owned_table.num_rows();
let limit = self.number_rows.unwrap_or(num_rows as u64);
let offset = self.offset_value.unwrap_or(0);
let possible_starting_row = if offset < 0 {
num_rows as i128 + i128::from(offset)
} else {
i128::from(offset)
};
let possible_ending_row = (possible_starting_row + i128::from(limit)).min(num_rows as i128);
let starting_row = usize::try_from(possible_starting_row).map_err(|_| {
PostprocessingError::InvalidSliceIndex {
index: possible_starting_row,
}
})?;
let ending_row = usize::try_from(possible_ending_row).map_err(|_| {
PostprocessingError::InvalidSliceIndex {
index: possible_ending_row,
}
})?;
Ok(OwnedTable::<S>::try_from_iter(
owned_table
.into_inner()
.into_iter()
.map(|(identifier, column)| (identifier, column.slice(starting_row, ending_row))),
)
.expect("Sliced columns of an existing table should have equal length"))
}
}