Skip to content

Commit 02a752b

Browse files
committed
remap children in update()
1 parent 858f66a commit 02a752b

File tree

1 file changed

+44
-27
lines changed

1 file changed

+44
-27
lines changed

datafusion/physical-expr/src/expressions/dynamic_filters.rs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,40 @@ impl DynamicFilterPhysicalExpr {
117117
}
118118
}
119119

120+
fn remap_children(
121+
children: &[Arc<dyn PhysicalExpr>],
122+
remapped_children: Option<&Vec<Arc<dyn PhysicalExpr>>>,
123+
expr: Arc<dyn PhysicalExpr>,
124+
) -> Result<Arc<dyn PhysicalExpr>> {
125+
if let Some(remapped_children) = remapped_children {
126+
// Remap the children to the new children
127+
// of the expression.
128+
expr.transform_up(|child| {
129+
// Check if this is any of our original children
130+
if let Some(pos) =
131+
children.iter().position(|c| c.as_ref() == child.as_ref())
132+
{
133+
// If so, remap it to the current children
134+
// of the expression.
135+
let new_child = Arc::clone(&remapped_children[pos]);
136+
Ok(Transformed::yes(new_child))
137+
} else {
138+
// Otherwise, just return the expression
139+
Ok(Transformed::no(child))
140+
}
141+
})
142+
.data()
143+
} else {
144+
// If we don't have any remapped children, just return the expression
145+
Ok(Arc::clone(&expr))
146+
}
147+
}
148+
120149
/// Get the current expression.
121150
/// This will return the current expression with any children
122151
/// remapped to match calls to [`PhysicalExpr::with_new_children`].
123152
pub fn current(&self) -> Result<Arc<dyn PhysicalExpr>> {
124-
let current = self
153+
let inner = self
125154
.inner
126155
.read()
127156
.map_err(|_| {
@@ -130,30 +159,9 @@ impl DynamicFilterPhysicalExpr {
130159
)
131160
})?
132161
.clone();
133-
if let Some(remapped_children) = &self.remapped_children {
134-
// Remap children to the current children
135-
// of the expression.
136-
current
137-
.transform_up(|expr| {
138-
// Check if this is any of our original children
139-
if let Some(pos) = self
140-
.children
141-
.iter()
142-
.position(|c| c.as_ref() == expr.as_ref())
143-
{
144-
// If so, remap it to the current children
145-
// of the expression.
146-
let new_child = Arc::clone(&remapped_children[pos]);
147-
Ok(Transformed::yes(new_child))
148-
} else {
149-
// Otherwise, just return the expression
150-
Ok(Transformed::no(expr))
151-
}
152-
})
153-
.data()
154-
} else {
155-
Ok(current)
156-
}
162+
let inner =
163+
Self::remap_children(&self.children, self.remapped_children.as_ref(), inner)?;
164+
Ok(inner)
157165
}
158166

159167
/// Update the current expression.
@@ -169,6 +177,12 @@ impl DynamicFilterPhysicalExpr {
169177
"Failed to acquire write lock for inner".to_string(),
170178
)
171179
})?;
180+
// Remap the children of the new expression to match the original children
181+
let new_expr = Self::remap_children(
182+
&self.children,
183+
self.remapped_children.as_ref(),
184+
new_expr,
185+
)?;
172186
*current = new_expr;
173187
Ok(())
174188
}
@@ -312,12 +326,15 @@ mod test {
312326
// Take an initial snapshot
313327
let snap = dynamic_filter.snapshot().unwrap().unwrap();
314328
insta::assert_snapshot!(format!("{snap:?}"), @r#"BinaryExpr { left: Column { name: "a", index: 0 }, op: Gt, right: Literal { value: Int32(42) }, fail_on_overflow: false }"#);
329+
let snap_string = snap.to_string();
315330
// Remap the children to the file schema
316331
let dynamic_filter =
317332
reassign_predicate_columns(dynamic_filter, &file_schema, false).unwrap();
318333
// Take a snapshot after remapping, the children in the snapshot should be remapped to the file schema
319-
let snap = dynamic_filter.snapshot().unwrap().unwrap();
320-
insta::assert_snapshot!(format!("{snap:?}"), @r#"BinaryExpr { left: Column { name: "a", index: 1 }, op: Gt, right: Literal { value: Int32(42) }, fail_on_overflow: false }"#);
334+
let new_snap = dynamic_filter.snapshot().unwrap().unwrap();
335+
insta::assert_snapshot!(format!("{new_snap:?}"), @r#"BinaryExpr { left: Column { name: "a", index: 1 }, op: Gt, right: Literal { value: Int32(42) }, fail_on_overflow: false }"#);
336+
// The original snapshot should not have changed
337+
assert_eq!(snap.to_string(), snap_string);
321338
}
322339

323340
#[test]

0 commit comments

Comments
 (0)