use std::fmt::{self, Display, Formatter};
use std::sync::Arc;
use crate::physical_expr::{PhysicalExpr, with_new_children_if_necessary};
use datafusion_common::Result;
use datafusion_common::tree_node::{ConcreteTreeNode, DynTreeNode};
impl DynTreeNode for dyn PhysicalExpr {
fn arc_children(&self) -> Vec<&Arc<Self>> {
self.children()
}
fn with_new_arc_children(
&self,
arc_self: Arc<Self>,
new_children: Vec<Arc<Self>>,
) -> Result<Arc<Self>> {
with_new_children_if_necessary(arc_self, new_children)
}
}
#[derive(Debug)]
pub struct ExprContext<T: Sized> {
pub expr: Arc<dyn PhysicalExpr>,
pub data: T,
pub children: Vec<Self>,
}
impl<T> ExprContext<T> {
pub fn new(expr: Arc<dyn PhysicalExpr>, data: T, children: Vec<Self>) -> Self {
Self {
expr,
data,
children,
}
}
pub fn update_expr_from_children(mut self) -> Result<Self> {
let children_expr = self.children.iter().map(|c| Arc::clone(&c.expr)).collect();
self.expr = with_new_children_if_necessary(self.expr, children_expr)?;
Ok(self)
}
}
impl<T: Default> ExprContext<T> {
pub fn new_default(plan: Arc<dyn PhysicalExpr>) -> Self {
let children = plan
.children()
.into_iter()
.cloned()
.map(Self::new_default)
.collect();
Self::new(plan, Default::default(), children)
}
}
impl<T: Display> Display for ExprContext<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "expr: {:?}", self.expr)?;
write!(f, "data:{}", self.data)?;
write!(f, "")
}
}
impl<T> ConcreteTreeNode for ExprContext<T> {
fn children(&self) -> &[Self] {
&self.children
}
fn take_children(mut self) -> (Self, Vec<Self>) {
let children = std::mem::take(&mut self.children);
(self, children)
}
fn with_new_children(mut self, children: Vec<Self>) -> Result<Self> {
self.children = children;
self.update_expr_from_children()
}
}