@@ -582,7 +582,11 @@ impl TreeNodeRecursion {
582
582
583
583
/// Result of tree walk / transformation APIs
584
584
///
585
- /// API users control the transformation by returning:
585
+ /// `Transformed` is a wrapper around the tree node data (e.g. `Expr` or
586
+ /// `LogicalPlan`). It is used to indicate whether the node was transformed
587
+ /// and how the recursion should proceed.
588
+ ///
589
+ /// [`TreeNode`] API users control the transformation by returning:
586
590
/// - The resulting (possibly transformed) node,
587
591
/// - `transformed`: flag indicating whether any change was made to the node
588
592
/// - `tnr`: [`TreeNodeRecursion`] specifying how to proceed with the recursion.
@@ -592,7 +596,66 @@ impl TreeNodeRecursion {
592
596
/// - `transformed`: flag indicating whether any change was made to the node
593
597
/// - `tnr`: [`TreeNodeRecursion`] specifying how the recursion ended.
594
598
///
595
- /// Example APIs:
599
+ /// See also
600
+ /// * [`Transformed::update_data`] to modify the node without changing the `transformed` flag
601
+ /// * [`Transformed::map_data`] for fallable operation that return the same type
602
+ /// * [`Transformed::transform_data`] to chain fallable transformations
603
+ /// * [`TransformedResult`] for working with `Result<Transformed<U>>`
604
+ ///
605
+ /// # Examples
606
+ ///
607
+ /// Use [`Transformed::yes`] and [`Transformed::no`] to signal that a node was
608
+ /// rewritten and the recursion should continue:
609
+ ///
610
+ /// ```
611
+ /// # use datafusion_common::tree_node::Transformed;
612
+ /// # // note use i64 instead of Expr as Expr is not in datafusion-common
613
+ /// # fn orig_expr() -> i64 { 1 }
614
+ /// # fn make_new_expr(i: i64) -> i64 { 2 }
615
+ /// let expr = orig_expr();
616
+ ///
617
+ /// // Create a new `Transformed` object signaling the node was not rewritten
618
+ /// let ret = Transformed::no(expr.clone());
619
+ /// assert!(!ret.transformed);
620
+ ///
621
+ /// // Create a new `Transformed` object signaling the node was rewritten
622
+ /// let ret = Transformed::yes(expr);
623
+ /// assert!(ret.transformed)
624
+ /// ```
625
+ ///
626
+ /// Access the node within the `Transformed` object:
627
+ /// ```
628
+ /// # use datafusion_common::tree_node::Transformed;
629
+ /// # // note use i64 instead of Expr as Expr is not in datafusion-common
630
+ /// # fn orig_expr() -> i64 { 1 }
631
+ /// # fn make_new_expr(i: i64) -> i64 { 2 }
632
+ /// let expr = orig_expr();
633
+ ///
634
+ /// // `Transformed` object signaling the node was not rewritten
635
+ /// let ret = Transformed::no(expr.clone());
636
+ /// // Access the inner object using .data
637
+ /// assert_eq!(expr, ret.data);
638
+ /// ```
639
+ ///
640
+ /// Transform the node within the `Transformed` object.
641
+ ///
642
+ /// ```
643
+ /// # use datafusion_common::tree_node::Transformed;
644
+ /// # // note use i64 instead of Expr as Expr is not in datafusion-common
645
+ /// # fn orig_expr() -> i64 { 1 }
646
+ /// # fn make_new_expr(i: i64) -> i64 { 2 }
647
+ /// let expr = orig_expr();
648
+ /// let ret = Transformed::no(expr.clone())
649
+ /// .transform_data(|expr| {
650
+ /// // closure returns a result and potentially transforms the node
651
+ /// // in this example, it does transform the node
652
+ /// let new_expr = make_new_expr(expr);
653
+ /// Ok(Transformed::yes(new_expr))
654
+ /// }).unwrap();
655
+ /// // transformed flag is the union of the original ans closure's transformed flag
656
+ /// assert!(ret.transformed);
657
+ /// ```
658
+ /// # Example APIs that use `TreeNode`
596
659
/// - [`TreeNode`],
597
660
/// - [`TreeNode::rewrite`],
598
661
/// - [`TreeNode::transform_down`],
@@ -833,6 +896,22 @@ macro_rules! map_until_stop_and_collect {
833
896
}
834
897
835
898
/// Transformation helper to access [`Transformed`] fields in a [`Result`] easily.
899
+ ///
900
+ /// # Example
901
+ /// Access the internal data of a `Result<Transformed<T>>`
902
+ /// as a `Result<T>` using the `data` method:
903
+ /// ```
904
+ /// # use datafusion_common::Result;
905
+ /// # use datafusion_common::tree_node::{Transformed, TransformedResult};
906
+ /// # // note use i64 instead of Expr as Expr is not in datafusion-common
907
+ /// # fn update_expr() -> i64 { 1 }
908
+ /// # fn main() -> Result<()> {
909
+ /// let transformed: Result<Transformed<_>> = Ok(Transformed::yes(update_expr()));
910
+ /// // access the internal data of the transformed result, or return the error
911
+ /// let transformed_expr = transformed.data()?;
912
+ /// # Ok(())
913
+ /// # }
914
+ /// ```
836
915
pub trait TransformedResult < T > {
837
916
fn data ( self ) -> Result < T > ;
838
917
0 commit comments