use glaredb_error::{DbError, Result, ResultExt};
use super::OperatorPlanState;
use crate::execution::operators::hash_aggregate::{Aggregates, PhysicalHashAggregate};
use crate::execution::operators::project::PhysicalProject;
use crate::execution::operators::{PlannedOperator, PlannedOperatorWithChildren};
use crate::expr::physical::column_expr::PhysicalColumnExpr;
use crate::logical::logical_materialization::LogicalMagicMaterializationScan;
use crate::logical::operator::Node;
impl OperatorPlanState<'_> {
pub fn plan_magic_materialize_scan(
&mut self,
scan: Node<LogicalMagicMaterializationScan>,
) -> Result<PlannedOperatorWithChildren> {
let mat_op = self.materializations.get(&scan.node.mat).ok_or_else(|| {
DbError::new(format!(
"Missing materialization for ref: {}",
scan.node.mat
))
})?;
let scan_op = PlannedOperatorWithChildren {
operator: mat_op.operator.clone(),
children: Vec::new(),
};
let materialized_refs = &self
.bind_context
.get_materialization(scan.node.mat)?
.table_refs;
let projections = self
.expr_planner
.plan_scalars(materialized_refs, &scan.node.projections)
.context("Failed to plan projections out of materialization")?;
let distinct_exprs: Vec<_> = projections
.iter()
.enumerate()
.map(|(idx, proj)| PhysicalColumnExpr::new(idx, proj.datatype()))
.collect();
let proj_op = PlannedOperatorWithChildren {
operator: PlannedOperator::new_execute(
self.id_gen.next_id(),
PhysicalProject::new(projections),
),
children: vec![scan_op],
};
let grouping_set = (0..distinct_exprs.len()).collect();
let aggregates = Aggregates {
groups: distinct_exprs,
grouping_functions: Vec::new(),
aggregates: Vec::new(),
};
let agg = PhysicalHashAggregate::new(aggregates, vec![grouping_set]);
let agg_op = PlannedOperatorWithChildren {
operator: PlannedOperator::new_execute(self.id_gen.next_id(), agg),
children: vec![proj_op],
};
Ok(agg_op)
}
}