use crate::error::DbError;
use super::pagination_value::value_to_usize;
use crate::executor::context::ExecutionContext;
use crate::executor::projection::eval_top_n;
use crate::executor::query::plan::RelationalQuery;
use super::super::QueryExecutor;
pub(crate) fn apply_pagination(
executor: &QueryExecutor<'_>,
query: &RelationalQuery,
mut final_rows: Vec<Vec<crate::types::Value>>,
ctx: &mut ExecutionContext,
) -> Result<Vec<Vec<crate::types::Value>>, DbError> {
if let Some(top) = query.pagination.top.clone() {
let n = eval_top_n(
&top,
ctx,
executor.catalog,
executor.storage,
executor.clock,
)?;
if final_rows.len() > n {
final_rows.truncate(n);
}
}
if let Some(offset_expr) = query.pagination.offset.clone() {
let offset_val = crate::executor::evaluator::eval_expr(
&offset_expr,
&[],
ctx,
executor.catalog,
executor.storage,
executor.clock,
)?;
let offset_n = value_to_usize(offset_val);
if offset_n < final_rows.len() {
final_rows = final_rows[offset_n..].to_vec();
} else {
final_rows = vec![];
}
if let Some(fetch_expr) = query.pagination.fetch.clone() {
let fetch_val = crate::executor::evaluator::eval_expr(
&fetch_expr,
&[],
ctx,
executor.catalog,
executor.storage,
executor.clock,
)?;
let fetch_n = value_to_usize(fetch_val);
if final_rows.len() > fetch_n {
final_rows.truncate(fetch_n);
}
}
}
Ok(final_rows)
}