1mod fold;
9mod visitor;
10
11use std::marker::PhantomData;
12use std::sync::Arc;
13
14pub use fold::FoldDownContext;
15pub use fold::FoldUp;
16pub use fold::NodeFolderContext;
17pub use visitor::pre_order_visit_down;
18use vortex_error::VortexResult;
19
20use crate::expr::BoundExpression;
21use crate::expr::Expression;
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum TraversalOrder {
26 Skip,
30 Stop,
32 Continue,
34}
35
36impl TraversalOrder {
37 pub fn visit_children<F: FnOnce() -> VortexResult<TraversalOrder>>(
39 self,
40 f: F,
41 ) -> VortexResult<TraversalOrder> {
42 match self {
43 Self::Skip => Ok(TraversalOrder::Continue),
44 Self::Stop => Ok(self),
45 Self::Continue => f(),
46 }
47 }
48
49 pub fn visit_parent<F: FnOnce() -> VortexResult<TraversalOrder>>(
51 self,
52 f: F,
53 ) -> VortexResult<TraversalOrder> {
54 match self {
55 Self::Continue => f(),
56 Self::Skip | Self::Stop => Ok(self),
57 }
58 }
59}
60
61#[derive(Debug, Clone)]
62pub struct Transformed<T> {
63 pub value: T,
65 pub order: TraversalOrder,
67 pub changed: bool,
69}
70
71impl<T> Transformed<T> {
72 pub fn yes(value: T) -> Self {
73 Self {
74 value,
75 order: TraversalOrder::Continue,
76 changed: true,
77 }
78 }
79
80 pub fn no(value: T) -> Self {
81 Self {
82 value,
83 order: TraversalOrder::Continue,
84 changed: false,
85 }
86 }
87
88 pub fn into_inner(self) -> T {
89 self.value
90 }
91
92 pub fn map<O, F: FnOnce(T) -> O>(self, f: F) -> Transformed<O> {
94 Transformed {
95 value: f(self.value),
96 order: self.order,
97 changed: self.changed,
98 }
99 }
100}
101
102pub trait NodeVisitor<'a> {
103 type NodeTy: Node;
104
105 fn visit_down(&mut self, node: &'a Self::NodeTy) -> VortexResult<TraversalOrder> {
106 _ = node;
107 Ok(TraversalOrder::Continue)
108 }
109
110 fn visit_up(&mut self, node: &'a Self::NodeTy) -> VortexResult<TraversalOrder> {
111 _ = node;
112 Ok(TraversalOrder::Continue)
113 }
114}
115
116pub trait NodeRewriter: Sized {
117 type NodeTy: Node;
118
119 fn visit_down(&mut self, node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
120 Ok(Transformed::no(node))
121 }
122
123 fn visit_up(&mut self, node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
124 Ok(Transformed::no(node))
125 }
126}
127
128pub trait Node: Sized + Clone {
129 fn apply_children<'a, F: FnMut(&'a Self) -> VortexResult<TraversalOrder>>(
133 &'a self,
134 f: F,
135 ) -> VortexResult<TraversalOrder>;
136
137 fn map_children<F: FnMut(Self) -> VortexResult<Transformed<Self>>>(
141 self,
142 f: F,
143 ) -> VortexResult<Transformed<Self>>;
144
145 fn iter_children<T>(&self, f: impl FnOnce(&mut dyn Iterator<Item = &Self>) -> T) -> T;
147
148 fn children_count(&self) -> usize;
150}
151
152pub trait NodeExt: Node {
153 fn rewrite<R: NodeRewriter<NodeTy = Self>>(
155 self,
156 rewriter: &mut R,
157 ) -> VortexResult<Transformed<Self>> {
158 let mut transformed = rewriter.visit_down(self)?;
159
160 let transformed = match transformed.order {
161 TraversalOrder::Stop => Ok(transformed),
162 TraversalOrder::Skip => {
163 transformed.order = TraversalOrder::Continue;
164 Ok(transformed)
165 }
166 TraversalOrder::Continue => transformed
167 .value
168 .map_children(|c| c.rewrite(rewriter))
169 .map(|mut t| {
170 t.changed |= transformed.changed;
171 t
172 }),
173 }?;
174
175 match transformed.order {
176 TraversalOrder::Stop | TraversalOrder::Skip => Ok(transformed),
177 TraversalOrder::Continue => {
178 let mut up_rewrite = rewriter.visit_up(transformed.value)?;
179 up_rewrite.changed |= transformed.changed;
180 Ok(up_rewrite)
181 }
182 }
183 }
184
185 fn accept<'a, V: NodeVisitor<'a, NodeTy = Self>>(
187 &'a self,
188 visitor: &mut V,
189 ) -> VortexResult<TraversalOrder> {
190 visitor
191 .visit_down(self)?
192 .visit_children(|| self.apply_children(|c| c.accept(visitor)))?
193 .visit_parent(|| visitor.visit_up(self))
194 }
195
196 fn transform_down<F: FnMut(Self) -> VortexResult<Transformed<Self>>>(
198 self,
199 f: F,
200 ) -> VortexResult<Transformed<Self>> {
201 let mut rewriter = FnRewriter {
202 f,
203 _data: PhantomData,
204 };
205
206 self.rewrite(&mut rewriter)
207 }
208
209 fn fold_context<R, F: NodeFolderContext<NodeTy = Self, Result = R>>(
211 self,
212 ctx: &F::Context,
213 folder: &mut F,
214 ) -> VortexResult<FoldUp<R>> {
215 let transformed = folder.visit_down(ctx, &self)?;
216 let ctx = match transformed {
217 FoldDownContext::Continue(ctx) => ctx,
218 FoldDownContext::Skip(r) => return Ok(FoldUp::Continue(r)),
219 FoldDownContext::Stop(r) => return Ok(FoldUp::Stop(r)),
220 };
221
222 let mut children = Vec::with_capacity(self.children_count());
223 let mut stop_result = None;
224 self.iter_children(|children_iter| -> VortexResult<()> {
225 for c in children_iter {
226 let t = c.clone().fold_context(&ctx, folder)?;
227 match t {
228 FoldUp::Stop(r) => {
229 stop_result = Some(r);
230 return Ok(());
231 }
232 FoldUp::Continue(r) => {
233 children.push(r);
234 }
235 }
236 }
237 Ok(())
238 })?;
239
240 if let Some(result) = stop_result {
241 return Ok(FoldUp::Stop(result));
242 }
243
244 folder.visit_up(self, &ctx, children)
245 }
246}
247
248impl<T: Node> NodeExt for T {}
249
250struct FnRewriter<F, T> {
251 f: F,
252 _data: PhantomData<T>,
253}
254
255impl<F, T> NodeRewriter for FnRewriter<F, T>
256where
257 T: Node,
258 F: FnMut(T) -> VortexResult<Transformed<T>>,
259{
260 type NodeTy = T;
261
262 fn visit_down(&mut self, node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
263 (self.f)(node)
264 }
265}
266
267pub trait NodeContainer<'a, T: 'a>: Sized {
272 fn apply_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
274 &'a self,
275 f: F,
276 ) -> VortexResult<TraversalOrder>;
277
278 fn map_elements<F: FnMut(T) -> VortexResult<Transformed<T>>>(
280 self,
281 f: F,
282 ) -> VortexResult<Transformed<Self>>;
283}
284
285pub trait NodeRefContainer<'a, T: 'a>: Sized {
286 fn apply_ref_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
287 &self,
288 f: F,
289 ) -> VortexResult<TraversalOrder>;
290}
291
292impl<'a, T: 'a, C: NodeContainer<'a, T>> NodeRefContainer<'a, T> for &'a [C] {
293 fn apply_ref_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
294 &self,
295 mut f: F,
296 ) -> VortexResult<TraversalOrder> {
297 let mut order = TraversalOrder::Continue;
298
299 for c in *self {
300 order = c.apply_elements(&mut f)?;
301 match order {
302 TraversalOrder::Continue | TraversalOrder::Skip => {}
303 TraversalOrder::Stop => return Ok(TraversalOrder::Stop),
304 }
305 }
306
307 Ok(order)
308 }
309}
310
311impl<'a, T: 'a, C: NodeContainer<'a, T>> NodeContainer<'a, T> for Box<C> {
312 fn apply_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
313 &'a self,
314 f: F,
315 ) -> VortexResult<TraversalOrder> {
316 self.as_ref().apply_elements(f)
317 }
318
319 fn map_elements<F: FnMut(T) -> VortexResult<Transformed<T>>>(
320 self,
321 f: F,
322 ) -> VortexResult<Transformed<Box<C>>> {
323 Ok((*self).map_elements(f)?.map(Box::new))
324 }
325}
326
327impl<'a, T, C> NodeContainer<'a, T> for Arc<C>
328where
329 T: 'a,
330 C: NodeContainer<'a, T> + Clone,
331{
332 fn apply_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
333 &'a self,
334 f: F,
335 ) -> VortexResult<TraversalOrder> {
336 self.as_ref().apply_elements(f)
337 }
338
339 fn map_elements<F: FnMut(T) -> VortexResult<Transformed<T>>>(
340 self,
341 f: F,
342 ) -> VortexResult<Transformed<Arc<C>>> {
343 Ok(Arc::unwrap_or_clone(self).map_elements(f)?.map(Arc::new))
344 }
345}
346
347impl<'a, T: 'a, C: NodeContainer<'a, T>> NodeContainer<'a, T> for [C; 2] {
348 fn apply_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
349 &'a self,
350 mut f: F,
351 ) -> VortexResult<TraversalOrder> {
352 let [lhs, rhs] = self;
353 match lhs.apply_elements(&mut f)? {
354 TraversalOrder::Skip | TraversalOrder::Continue => rhs.apply_elements(&mut f),
355 TraversalOrder::Stop => Ok(TraversalOrder::Stop),
356 }
357 }
358
359 fn map_elements<F: FnMut(T) -> VortexResult<Transformed<T>>>(
360 self,
361 mut f: F,
362 ) -> VortexResult<Transformed<[C; 2]>> {
363 let [lhs, rhs] = self;
364 let transformed = lhs.map_elements(&mut f)?;
365 match transformed.order {
366 TraversalOrder::Skip | TraversalOrder::Continue => {
367 let mut t = rhs.map_elements(&mut f)?;
368 t.changed |= transformed.changed;
369 Ok(t.map(|new_lhs| [new_lhs, transformed.value]))
370 }
371 TraversalOrder::Stop => Ok(transformed.map(|new_lhs| [new_lhs, rhs])),
372 }
373 }
374}
375
376impl<'a, T: 'a, C: NodeContainer<'a, T>> NodeContainer<'a, T> for Vec<C> {
377 fn apply_elements<F: FnMut(&'a T) -> VortexResult<TraversalOrder>>(
378 &'a self,
379 mut f: F,
380 ) -> VortexResult<TraversalOrder> {
381 let mut order = TraversalOrder::Continue;
382
383 for c in self {
384 order = c.apply_elements(&mut f)?;
385 match order {
386 TraversalOrder::Continue | TraversalOrder::Skip => {}
387 TraversalOrder::Stop => return Ok(TraversalOrder::Stop),
388 }
389 }
390
391 Ok(order)
392 }
393
394 fn map_elements<F: FnMut(T) -> VortexResult<Transformed<T>>>(
395 self,
396 mut f: F,
397 ) -> VortexResult<Transformed<Self>> {
398 let mut order = TraversalOrder::Continue;
399 let mut changed = false;
400
401 let value = self
402 .into_iter()
403 .map(|c| match order {
404 TraversalOrder::Continue | TraversalOrder::Skip => {
405 c.map_elements(&mut f).map(|result| {
406 order = result.order;
407 changed |= result.changed;
408 result.value
409 })
410 }
411 TraversalOrder::Stop => Ok(c),
412 })
413 .collect::<VortexResult<Vec<_>>>()?;
414
415 Ok(Transformed {
416 value,
417 order,
418 changed,
419 })
420 }
421}
422
423impl<'a> NodeContainer<'a, Self> for Expression {
424 fn apply_elements<F: FnMut(&'a Self) -> VortexResult<TraversalOrder>>(
425 &'a self,
426 mut f: F,
427 ) -> VortexResult<TraversalOrder> {
428 f(self)
429 }
430
431 fn map_elements<F: FnMut(Self) -> VortexResult<Transformed<Self>>>(
432 self,
433 mut f: F,
434 ) -> VortexResult<Transformed<Self>> {
435 f(self)
436 }
437}
438
439impl Node for Expression {
440 fn apply_children<'a, F: FnMut(&'a Self) -> VortexResult<TraversalOrder>>(
441 &'a self,
442 mut f: F,
443 ) -> VortexResult<TraversalOrder> {
444 self.children().apply_ref_elements(&mut f)
445 }
446
447 fn map_children<F: FnMut(Self) -> VortexResult<Transformed<Self>>>(
448 self,
449 f: F,
450 ) -> VortexResult<Transformed<Self>> {
451 let transformed = self.children().to_vec().map_elements(f)?;
452
453 if transformed.changed {
454 Ok(Transformed {
455 value: self.with_children(transformed.value)?,
456 order: transformed.order,
457 changed: true,
458 })
459 } else {
460 Ok(Transformed::no(self))
461 }
462 }
463
464 fn iter_children<T>(&self, f: impl FnOnce(&mut dyn Iterator<Item = &Self>) -> T) -> T {
465 f(&mut self.children().iter())
466 }
467
468 fn children_count(&self) -> usize {
469 self.children().len()
470 }
471}
472
473impl Node for BoundExpression {
474 fn apply_children<'a, F: FnMut(&'a Self) -> VortexResult<TraversalOrder>>(
475 &'a self,
476 mut f: F,
477 ) -> VortexResult<TraversalOrder> {
478 let BoundExpression::Scalar { children, .. } = self else {
479 return Ok(TraversalOrder::Continue);
480 };
481
482 for child in children.iter() {
483 match f(child)? {
484 TraversalOrder::Continue | TraversalOrder::Skip => {}
485 TraversalOrder::Stop => return Ok(TraversalOrder::Stop),
486 }
487 }
488
489 Ok(TraversalOrder::Continue)
490 }
491
492 fn map_children<F: FnMut(Self) -> VortexResult<Transformed<Self>>>(
493 self,
494 mut f: F,
495 ) -> VortexResult<Transformed<Self>> {
496 let BoundExpression::Scalar { children, .. } = &self else {
497 return Ok(Transformed::no(self));
498 };
499
500 let mut order = TraversalOrder::Continue;
501 let mut rewritten: Option<Vec<Self>> = None;
504
505 for (index, child) in children.iter().enumerate() {
506 let value = match order {
507 TraversalOrder::Continue | TraversalOrder::Skip => {
508 let result = f(child.clone())?;
509 order = result.order;
510 if result.changed && rewritten.is_none() {
511 let mut prefix = Vec::with_capacity(children.len());
512 prefix.extend_from_slice(&children[..index]);
513 rewritten = Some(prefix);
514 }
515 result.value
516 }
517 TraversalOrder::Stop => child.clone(),
518 };
519
520 if let Some(rewritten) = &mut rewritten {
521 rewritten.push(value);
522 }
523 }
524
525 match rewritten {
526 Some(rewritten) => Ok(Transformed {
527 value: self.with_children(rewritten)?,
528 order,
529 changed: true,
530 }),
531 None => Ok(Transformed::no(self)),
532 }
533 }
534
535 fn iter_children<T>(&self, f: impl FnOnce(&mut dyn Iterator<Item = &Self>) -> T) -> T {
536 match self {
537 BoundExpression::Scalar { children, .. } => f(&mut children.iter()),
538 BoundExpression::Root { .. } => f(&mut std::iter::empty()),
539 }
540 }
541
542 fn children_count(&self) -> usize {
543 match self {
544 BoundExpression::Scalar { children, .. } => children.len(),
545 BoundExpression::Root { .. } => 0,
546 }
547 }
548}
549
550#[cfg(test)]
551mod tests {
552 use vortex_error::VortexResult;
553 use vortex_utils::aliases::hash_set::HashSet;
554
555 use super::NodeExt;
556 use super::NodeRewriter;
557 use super::NodeVisitor;
558 use super::Transformed;
559 use super::TraversalOrder;
560 use super::visitor::pre_order_visit_down;
561 use crate::expr::Expression;
562 use crate::expr::and;
563 use crate::expr::col;
564 use crate::expr::eq;
565 use crate::expr::is_root;
566 use crate::expr::lit;
567 use crate::expr::not_eq;
568 use crate::expr::root;
569 use crate::scalar_fn::fns::binary::Binary;
570 use crate::scalar_fn::fns::get_item::GetItem;
571 use crate::scalar_fn::fns::literal::Literal;
572 use crate::scalar_fn::fns::operators::Operator;
573
574 #[derive(Default)]
575 pub struct ExprLitCollector<'a>(pub Vec<&'a Expression>);
576
577 impl<'a> NodeVisitor<'a> for ExprLitCollector<'a> {
578 type NodeTy = Expression;
579
580 fn visit_down(&mut self, node: &'a Expression) -> VortexResult<TraversalOrder> {
581 if node.is::<Literal>() {
582 self.0.push(node)
583 }
584 Ok(TraversalOrder::Continue)
585 }
586
587 fn visit_up(&mut self, _node: &'a Expression) -> VortexResult<TraversalOrder> {
588 Ok(TraversalOrder::Continue)
589 }
590 }
591
592 fn expr_col_to_lit_transform(
593 node: Expression,
594 idx: &mut i32,
595 ) -> VortexResult<Transformed<Expression>> {
596 if node.is::<GetItem>() {
597 let lit_id = *idx;
598 *idx += 1;
599 Ok(Transformed::yes(lit(lit_id)))
600 } else {
601 Ok(Transformed::no(node))
602 }
603 }
604
605 #[derive(Default)]
606 pub struct SkipDownRewriter;
607
608 impl NodeRewriter for SkipDownRewriter {
609 type NodeTy = Expression;
610
611 fn visit_down(&mut self, node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
612 Ok(Transformed {
613 value: node,
614 order: TraversalOrder::Skip,
615 changed: false,
616 })
617 }
618
619 fn visit_up(&mut self, _node: Self::NodeTy) -> VortexResult<Transformed<Self::NodeTy>> {
620 Ok(Transformed::yes(root()))
621 }
622 }
623
624 #[test]
625 fn expr_deep_visitor_test() {
626 let col1: Expression = col("col1");
627 let lit1 = lit(1);
628 let expr = eq(col1, lit1);
629 let lit2 = lit(2);
630 let expr = and(expr, lit2);
631 let mut printer = ExprLitCollector::default();
632 expr.accept(&mut printer).unwrap();
633 assert_eq!(printer.0.len(), 2);
634 }
635
636 #[test]
637 fn expr_deep_mut_visitor_test() {
638 let col1: Expression = col("col1");
639 let col2: Expression = col("col2");
640 let expr = eq(col1, col2);
641 let lit2 = lit(2);
642 let expr = and(expr, lit2);
643
644 let mut idx = 0_i32;
645 let new = expr
646 .transform_down(|node| expr_col_to_lit_transform(node, &mut idx))
647 .unwrap();
648 assert!(new.changed);
649
650 let expr = new.value;
651
652 let mut printer = ExprLitCollector::default();
653 expr.accept(&mut printer).unwrap();
654 assert_eq!(printer.0.len(), 3);
655 }
656
657 #[test]
658 fn expr_skip_test() {
659 let col1: Expression = col("col1");
660 let col2: Expression = col("col2");
661 let expr1 = eq(col1, col2);
662 let col3: Expression = col("col3");
663 let col4: Expression = col("col4");
664 let expr2 = not_eq(col3, col4);
665 let expr = and(expr1, expr2);
666
667 let mut nodes = Vec::new();
668 pre_order_visit_down(&expr, |node: &Expression| {
669 if node.is::<GetItem>() {
670 nodes.push(node)
671 }
672 if let Some(operator) = node.as_opt::<Binary>()
673 && *operator == Operator::Eq
674 {
675 return Ok(TraversalOrder::Skip);
676 }
677 Ok(TraversalOrder::Continue)
678 })
679 .unwrap();
680
681 let nodes: HashSet<Expression> = HashSet::from_iter(nodes.into_iter().cloned());
682 assert_eq!(nodes, HashSet::from_iter([col("col3"), col("col4")]));
683 }
684
685 #[test]
686 fn expr_stop_test() {
687 let col1: Expression = col("col1");
688 let col2: Expression = col("col2");
689 let expr1 = eq(col1, col2);
690 let col3: Expression = col("col3");
691 let col4: Expression = col("col4");
692 let expr2 = not_eq(col3, col4);
693 let expr = and(expr1, expr2);
694
695 let mut nodes = Vec::new();
696 pre_order_visit_down(&expr, |node: &Expression| {
697 if node.is::<GetItem>() {
698 nodes.push(node)
699 }
700 if let Some(operator) = node.as_opt::<Binary>()
701 && *operator == Operator::Eq
702 {
703 return Ok(TraversalOrder::Stop);
704 }
705 Ok(TraversalOrder::Continue)
706 })
707 .unwrap();
708
709 assert!(nodes.is_empty());
710 }
711
712 #[test]
713 fn expr_skip_down_visit_up() {
714 let col = col("col");
715
716 let mut visitor = SkipDownRewriter;
717 let result = col.rewrite(&mut visitor).unwrap();
718
719 assert!(result.changed);
720 assert!(is_root(&result.value));
721 }
722}