Skip to content

Commit cdc5d00

Browse files
authored
Improve PhysicalExpr documentation (#9180)
1 parent 1a9b069 commit cdc5d00

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

datafusion/physical-expr/src/physical_expr.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,65 @@ use datafusion_expr::ColumnarValue;
3434

3535
use itertools::izip;
3636

37-
/// Expression that can be evaluated against a RecordBatch
37+
/// `PhysicalExpr` evaluate DataFusion expressions such as `A + 1`, or `CAST(c1
38+
/// AS int)`.
39+
///
40+
/// `PhysicalExpr` are the physical counterpart to [`Expr`] used in logical
41+
/// planning, and can be evaluated directly on a [`RecordBatch`]. They are
42+
/// normally created from `Expr` by a [`PhysicalPlanner`] and can be created
43+
/// directly using [`create_physical_expr`].
44+
///
3845
/// A Physical expression knows its type, nullability and how to evaluate itself.
46+
///
47+
/// [`PhysicalPlanner`]: https://docs.rs/datafusion/latest/datafusion/physical_planner/trait.PhysicalPlanner.html
48+
/// [`create_physical_expr`]: crate::create_physical_expr
49+
/// [`Expr`]: datafusion_expr::Expr
50+
///
51+
/// # Example: Create `PhysicalExpr` from `Expr`
52+
/// ```
53+
/// # use arrow_schema::{DataType, Field, Schema};
54+
/// # use datafusion_common::DFSchema;
55+
/// # use datafusion_expr::{Expr, col, lit};
56+
/// # use datafusion_physical_expr::create_physical_expr;
57+
/// # use datafusion_physical_expr::execution_props::ExecutionProps;
58+
/// // For a logical expression `a = 1`, we can create a physical expression
59+
/// let expr = col("a").eq(lit(1));
60+
/// // To create a PhysicalExpr we need 1. a schema
61+
/// let schema = Schema::new(vec![Field::new("a", DataType::Int32, true)]);
62+
/// let df_schema = DFSchema::try_from(schema).unwrap();
63+
/// // 2. ExecutionProps
64+
/// let props = ExecutionProps::new();
65+
/// // We can now create a PhysicalExpr:
66+
/// let physical_expr = create_physical_expr(&expr, &df_schema, &props).unwrap();
67+
/// ```
68+
///
69+
/// # Example: Executing a PhysicalExpr to obtain [`ColumnarValue`]
70+
/// ```
71+
/// # use std::sync::Arc;
72+
/// # use arrow_array::{cast::AsArray, BooleanArray, Int32Array, RecordBatch};
73+
/// # use arrow_schema::{DataType, Field, Schema};
74+
/// # use datafusion_common::{assert_batches_eq, DFSchema};
75+
/// # use datafusion_expr::{Expr, col, lit, ColumnarValue};
76+
/// # use datafusion_physical_expr::create_physical_expr;
77+
/// # use datafusion_physical_expr::execution_props::ExecutionProps;
78+
/// # let expr = col("a").eq(lit(1));
79+
/// # let schema = Schema::new(vec![Field::new("a", DataType::Int32, true)]);
80+
/// # let df_schema = DFSchema::try_from(schema.clone()).unwrap();
81+
/// # let props = ExecutionProps::new();
82+
/// // Given a PhysicalExpr, for `a = 1` we can evaluate it against a RecordBatch like this:
83+
/// let physical_expr = create_physical_expr(&expr, &df_schema, &props).unwrap();
84+
/// // Input of [1,2,3]
85+
/// let input_batch = RecordBatch::try_from_iter(vec![
86+
/// ("a", Arc::new(Int32Array::from(vec![1, 2, 3])) as _)
87+
/// ]).unwrap();
88+
/// // The result is a ColumnarValue (either an Array or a Scalar)
89+
/// let result = physical_expr.evaluate(&input_batch).unwrap();
90+
/// // In this case, a BooleanArray with the result of the comparison
91+
/// let ColumnarValue::Array(arr) = result else {
92+
/// panic!("Expected an array")
93+
/// };
94+
/// assert_eq!(arr.as_boolean(), &BooleanArray::from(vec![true, false, false]));
95+
/// ```
3996
pub trait PhysicalExpr: Send + Sync + Display + Debug + PartialEq<dyn Any> {
4097
/// Returns the physical expression as [`Any`] so that it can be
4198
/// downcast to a specific implementation.

0 commit comments

Comments
 (0)