use reifydb_core::{
interface::catalog::column::Column,
value::column::{columns::Columns, data::ColumnData},
};
use reifydb_routine::function::registry::Functions;
use reifydb_runtime::context::{RuntimeContext, clock::Clock};
use reifydb_type::{fragment::Fragment, params::Params, value::identity::IdentityId};
use crate::{
Result,
expression::{cast::cast_column_data, context::EvalContext},
vm::stack::SymbolTable,
};
pub(super) fn coerce_columns(
column_data: &[ColumnData],
columns: &[Column],
num_rows: usize,
) -> Result<Vec<ColumnData>> {
let runtime_ctx = RuntimeContext::with_clock(Clock::Real);
let ctx = EvalContext {
params: &Params::None,
symbols: &SymbolTable::new(),
functions: &Functions::empty(),
runtime_context: &runtime_ctx,
arena: None,
identity: IdentityId::root(),
is_aggregate_context: false,
columns: Columns::empty(),
row_count: num_rows,
target: None,
take: None,
};
let mut coerced_columns: Vec<ColumnData> = Vec::with_capacity(columns.len());
for (col_idx, col) in columns.iter().enumerate() {
let target = col.constraint.get_type();
let cast_target = target.inner_type().clone();
let source_data = &column_data[col_idx];
let coerced = cast_column_data(&ctx, source_data, cast_target, || Fragment::internal(&col.name))?;
coerced_columns.push(coerced);
}
Ok(coerced_columns)
}