Skip to content

Commit 1155b0b

Browse files
authored
Minor: Add more docs and examples for Transformed and TransformedResult (#11003)
1 parent 5316278 commit 1155b0b

File tree

1 file changed

+81
-2
lines changed

1 file changed

+81
-2
lines changed

datafusion/common/src/tree_node.rs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
/// ```
836915
pub trait TransformedResult<T> {
837916
fn data(self) -> Result<T>;
838917

0 commit comments

Comments
 (0)