use crate::{
db::{
QueryError,
schema::{AcceptedEnumCatalog, AcceptedEnumCatalogHandle, output_value_from_runtime},
session::sql::SqlStatementResult,
},
value::{OutputValue, Value},
};
type SqlProjectionPayloadComponents = (Vec<String>, Vec<Option<u32>>, Vec<Vec<Value>>, u32);
#[derive(Debug)]
pub(in crate::db::session::sql) struct SqlProjectionPayload {
columns: Vec<String>,
fixed_scales: Vec<Option<u32>>,
rows: Vec<Vec<Value>>,
row_count: u32,
enum_catalog: AcceptedEnumCatalogHandle,
}
impl SqlProjectionPayload {
#[must_use]
pub(in crate::db::session::sql) const fn new(
columns: Vec<String>,
fixed_scales: Vec<Option<u32>>,
rows: Vec<Vec<Value>>,
row_count: u32,
enum_catalog: AcceptedEnumCatalogHandle,
) -> Self {
Self {
columns,
fixed_scales,
rows,
row_count,
enum_catalog,
}
}
#[must_use]
pub(in crate::db::session::sql) fn into_components(self) -> SqlProjectionPayloadComponents {
(self.columns, self.fixed_scales, self.rows, self.row_count)
}
pub(in crate::db::session::sql) fn into_statement_result(
self,
) -> Result<SqlStatementResult, QueryError> {
sql_projection_statement_result_from_value_rows(
self.enum_catalog.catalog(),
self.columns,
self.fixed_scales,
self.rows,
self.row_count,
)
}
}
pub(in crate::db::session::sql) fn sql_projection_statement_result_from_value_rows(
catalog: &AcceptedEnumCatalog,
columns: Vec<String>,
fixed_scales: Vec<Option<u32>>,
rows: impl IntoIterator<Item = Vec<Value>>,
row_count: u32,
) -> Result<SqlStatementResult, QueryError> {
Ok(SqlStatementResult::Projection {
columns,
fixed_scales,
rows: rows
.into_iter()
.map(|row| sql_output_row_from_value_row(catalog, row))
.collect::<Result<Vec<_>, _>>()?,
row_count,
})
}
pub(in crate::db::session::sql) fn sql_projection_statement_result_from_fallible_value_rows(
catalog: &AcceptedEnumCatalog,
columns: Vec<String>,
fixed_scales: Vec<Option<u32>>,
rows: impl IntoIterator<Item = Result<Vec<Value>, QueryError>>,
row_count: u32,
) -> Result<SqlStatementResult, QueryError> {
let rows = rows
.into_iter()
.map(|row| row.and_then(|row| sql_output_row_from_value_row(catalog, row)))
.collect::<Result<Vec<_>, _>>()?;
Ok(SqlStatementResult::Projection {
columns,
fixed_scales,
rows,
row_count,
})
}
fn sql_output_row_from_value_row(
catalog: &AcceptedEnumCatalog,
row: Vec<Value>,
) -> Result<Vec<OutputValue>, QueryError> {
row.iter()
.map(|value| {
output_value_from_runtime(catalog, value).map_err(|_error| QueryError::invariant())
})
.collect()
}