MCPcopy Create free account
hub / github.com/apache/datafusion / update_expr

Function update_expr

datafusion/physical-expr/src/projection.rs:938–1010  ·  view source on GitHub ↗

The function projects / unprojects an expression with respect to set of projection expressions. See also [`ProjectionExprs::unproject_expr`] and [`ProjectionExprs::project_expr`] 1) When `unproject` is `true`: Rewrites an expression with respect to the projection expressions, effectively "unprojecting" it to reference the original input columns. For example, given the expressions `a@1 + b@2` a

(
    expr: &Arc<dyn PhysicalExpr>,
    projected_exprs: &[ProjectionExpr],
    unproject: bool,
)

Source from the content-addressed store, hash-verified

936///
937/// In this case, `a@3` references index 3, which is out of bounds for `projected_exprs` (which has length 2).
938pub fn update_expr(
939 expr: &Arc<dyn PhysicalExpr>,
940 projected_exprs: &[ProjectionExpr],
941 unproject: bool,
942) -> Result<Option<Arc<dyn PhysicalExpr>>> {
943 #[derive(Debug, PartialEq)]
944 enum RewriteState {
945 /// The expression is unchanged.
946 Unchanged,
947 /// Some part of the expression has been rewritten
948 RewrittenValid,
949 /// Some part of the expression has been rewritten, but some column
950 /// references could not be.
951 RewrittenInvalid,
952 }
953
954 let mut state = RewriteState::Unchanged;
955
956 let new_expr = Arc::clone(expr)
957 .transform_up(|expr| {
958 if state == RewriteState::RewrittenInvalid {
959 return Ok(Transformed::no(expr));
960 }
961
962 let Some(column) = expr.downcast_ref::<Column>() else {
963 return Ok(Transformed::no(expr));
964 };
965 if unproject {
966 state = RewriteState::RewrittenValid;
967 // Update the index of `column`:
968 let projected_expr = projected_exprs.get(column.index()).ok_or_else(|| {
969 internal_datafusion_err!(
970 "Column index {} out of bounds for projected expressions of length {}",
971 column.index(),
972 projected_exprs.len()
973 )
974 })?;
975 Ok(Transformed::yes(Arc::clone(&projected_expr.expr)))
976 } else {
977 // default to invalid, in case we can't find the relevant column
978 state = RewriteState::RewrittenInvalid;
979 // Determine how to update `column` to accommodate `projected_exprs`
980 projected_exprs
981 .iter()
982 .enumerate()
983 .find_map(|(index, proj_expr)| {
984 proj_expr.expr.downcast_ref::<Column>().and_then(
985 |projected_column| {
986 (column.name().eq(projected_column.name())
987 && column.index() == projected_column.index())
988 .then(|| {
989 state = RewriteState::RewrittenValid;
990 Arc::new(Column::new(&proj_expr.alias, index)) as _
991 })
992 },
993 )
994 })
995 .map_or_else(

Calls 8

newFunction · 0.85
transform_upMethod · 0.80
dataMethod · 0.45
getMethod · 0.45
indexMethod · 0.45
iterMethod · 0.45
eqMethod · 0.45
nameMethod · 0.45

Used in the wild real call sites across dependent graphs

searching dependent graphs…