use super::*;
pub(super) fn handle(
op: &mut UnaryOperator,
input: &mut StreamingExecutor,
) -> Result<Option<DataChunk>, QueryError> {
let UnaryOperatorKind::Assign { assignments, state } = &mut op.kind else {
return Err(QueryError::execution(
"assign::handle called for a non-assign unary operator".to_string(),
));
};
loop {
if let Some(mut chunk) = input.advance()? {
chunk.materialize_selection_by("Assign");
let multiplicity = chunk.multiplicity();
let mut new_cols: Vec<Vec<Value>> = Vec::with_capacity(assignments.len());
for (_col_name, expr) in assignments.iter() {
let col = match chunk.evaluate_expression(expr, Some(&state.env)) {
Ok(col) => col,
Err(_) => {
vec![Value::Null(linkrs_core::value::NullType::Null); chunk.len()]
}
};
new_cols.push(col);
}
for (i, row) in chunk.rows.iter_mut().enumerate() {
for col in &new_cols {
row.push(col[i].clone());
}
}
if !chunk.rows.is_empty() {
let mut rebuilt =
DataChunk::new_with_layout(chunk.rows, Arc::clone(&op.output_layout))
.with_multiplicity(multiplicity);
rebuilt.build_typed_columns(true);
return Ok(Some(rebuilt));
}
} else {
return Ok(None);
}
}
}