@@ -582,7 +582,11 @@ impl TreeNodeRecursion {
582582
583583/// Result of tree walk / transformation APIs
584584///
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:
586590/// - The resulting (possibly transformed) node,
587591/// - `transformed`: flag indicating whether any change was made to the node
588592/// - `tnr`: [`TreeNodeRecursion`] specifying how to proceed with the recursion.
@@ -592,7 +596,66 @@ impl TreeNodeRecursion {
592596/// - `transformed`: flag indicating whether any change was made to the node
593597/// - `tnr`: [`TreeNodeRecursion`] specifying how the recursion ended.
594598///
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`
596659/// - [`TreeNode`],
597660/// - [`TreeNode::rewrite`],
598661/// - [`TreeNode::transform_down`],
@@ -833,6 +896,22 @@ macro_rules! map_until_stop_and_collect {
833896}
834897
835898/// 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+ /// ```
836915pub trait TransformedResult < T > {
837916 fn data ( self ) -> Result < T > ;
838917
0 commit comments