Skip to content

Commit f3d20d0

Browse files
committed
Migrate usages away from with_new_children.
1 parent ad3df55 commit f3d20d0

16 files changed

Lines changed: 99 additions & 59 deletions

File tree

datafusion/catalog/src/memory/table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ impl ExecutionPlan for DmlResultExec {
574574
fn replace_children(
575575
self: Arc<Self>,
576576
_: Vec<Arc<dyn ExecutionPlan>>,
577-
_: datafusion_physical_plan::ChildrenPropertiesHint,
577+
_: ChildrenPropertiesHint,
578578
) -> Result<Arc<dyn ExecutionPlan>> {
579579
Ok(self)
580580
}

datafusion/core/src/physical_planner.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4981,10 +4981,16 @@ digraph {
49814981
// ok plan
49824982
let ok_node: Arc<dyn ExecutionPlan> = Arc::new(OkExtensionNode(vec![]));
49834983
let child = Arc::clone(&ok_node);
4984-
let ok_plan = Arc::clone(&ok_node).with_new_children(vec![
4985-
Arc::clone(&child).with_new_children(vec![Arc::clone(&child)])?,
4986-
Arc::clone(&child),
4987-
])?;
4984+
let ok_plan = Arc::clone(&ok_node).replace_children(
4985+
vec![
4986+
Arc::clone(&child).replace_children(
4987+
vec![Arc::clone(&child)],
4988+
ChildrenPropertiesHint::Recompute,
4989+
)?,
4990+
Arc::clone(&child),
4991+
],
4992+
ChildrenPropertiesHint::Recompute,
4993+
)?;
49884994

49894995
// Test: check should pass with same schema
49904996
let equal_schema = ok_plan.schema();
@@ -5016,10 +5022,16 @@ digraph {
50165022

50175023
// Test: should fail when descendent extension node fails
50185024
let failing_node: Arc<dyn ExecutionPlan> = Arc::new(InvariantFailsExtensionNode);
5019-
let invalid_plan = ok_node.with_new_children(vec![
5020-
Arc::clone(&child).with_new_children(vec![Arc::clone(&failing_node)])?,
5021-
Arc::clone(&child),
5022-
])?;
5025+
let invalid_plan = ok_node.replace_children(
5026+
vec![
5027+
Arc::clone(&child).replace_children(
5028+
vec![Arc::clone(&failing_node)],
5029+
ChildrenPropertiesHint::Recompute,
5030+
)?,
5031+
Arc::clone(&child),
5032+
],
5033+
ChildrenPropertiesHint::Recompute,
5034+
)?;
50235035
let result = OptimizationInvariantChecker::new(&rule)
50245036
.check(&invalid_plan, &ok_plan.schema());
50255037
if cfg!(debug_assertions) {
@@ -5105,10 +5117,16 @@ digraph {
51055117
let failing_node: Arc<dyn ExecutionPlan> = Arc::new(ExecutableInvariantFails);
51065118
let ok_node: Arc<dyn ExecutionPlan> = Arc::new(OkExtensionNode(vec![]));
51075119
let child = Arc::clone(&ok_node);
5108-
let plan = ok_node.with_new_children(vec![
5109-
Arc::clone(&child).with_new_children(vec![Arc::clone(&failing_node)])?,
5110-
Arc::clone(&child),
5111-
])?;
5120+
let plan = ok_node.replace_children(
5121+
vec![
5122+
Arc::clone(&child).replace_children(
5123+
vec![Arc::clone(&failing_node)],
5124+
ChildrenPropertiesHint::Recompute,
5125+
)?,
5126+
Arc::clone(&child),
5127+
],
5128+
ChildrenPropertiesHint::Recompute,
5129+
)?;
51125130
let expected_err = InvariantChecker(InvariantLevel::Executable)
51135131
.check(&plan)
51145132
.unwrap_err();

datafusion/ffi/src/execution_plan.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ unsafe extern "C" fn with_new_children_fn_wrapper(
151151
.collect();
152152

153153
let children = sresult_return!(children);
154-
let new_plan = sresult_return!(inner_plan.with_new_children(children));
154+
let new_plan = sresult_return!(
155+
inner_plan.replace_children(children, ChildrenPropertiesHint::Recompute)
156+
);
155157

156158
FFI_Result::Ok(FFI_ExecutionPlan::new(new_plan, runtime))
157159
}
@@ -268,7 +270,7 @@ fn pass_runtime_to_children(
268270
// If the parent is foreign and the child is local to this library, then when
269271
// we called `children()` above we will get something other than a
270272
// `ForeignExecutionPlan`. In this case wrap the plan in a `ForeignExecutionPlan`
271-
// because when we call `with_new_children` below it will extract the
273+
// because when we call `replace_children` below it will extract the
272274
// FFI plan that does contain the runtime.
273275
if plan_is_foreign && !child.is::<ForeignExecutionPlan>() {
274276
updated_children = true;
@@ -281,7 +283,9 @@ fn pass_runtime_to_children(
281283
})
282284
.collect::<Result<Vec<_>>>()?;
283285
if updated_children {
284-
Arc::clone(plan).with_new_children(children).map(Some)
286+
Arc::clone(plan)
287+
.replace_children(children, ChildrenPropertiesHint::Recompute)
288+
.map(Some)
285289
} else {
286290
Ok(None)
287291
}
@@ -636,7 +640,8 @@ pub mod tests {
636640
assert_eq!(parent_foreign.children().len(), 0);
637641
assert_eq!(child_foreign.children().len(), 0);
638642

639-
let parent_foreign = parent_foreign.with_new_children(vec![child_foreign])?;
643+
let parent_foreign = parent_foreign
644+
.replace_children(vec![child_foreign], ChildrenPropertiesHint::Recompute)?;
640645
assert_eq!(parent_foreign.children().len(), 1);
641646

642647
// Version 2: Adding child to the local plan
@@ -646,7 +651,8 @@ pub mod tests {
646651
let child_foreign = <Arc<dyn ExecutionPlan>>::try_from(&child_local)?;
647652

648653
let parent_plan = Arc::new(EmptyExec::new(Arc::clone(&schema)));
649-
let parent_plan = parent_plan.with_new_children(vec![child_foreign])?;
654+
let parent_plan = parent_plan
655+
.replace_children(vec![child_foreign], ChildrenPropertiesHint::Recompute)?;
650656
let mut parent_local = FFI_ExecutionPlan::new(parent_plan, None);
651657
parent_local.library_marker_id = crate::mock_foreign_marker_id;
652658
let parent_foreign = <Arc<dyn ExecutionPlan>>::try_from(&parent_local)?;

datafusion/ffi/tests/ffi_execution_plan.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod tests {
2525
use datafusion_ffi::execution_plan::ForeignExecutionPlan;
2626
use datafusion_ffi::execution_plan::{ExecutionPlanPrivateData, tests::EmptyExec};
2727
use datafusion_ffi::tests::utils::get_module;
28-
use datafusion_physical_plan::ExecutionPlan;
28+
use datafusion_physical_plan::{ChildrenPropertiesHint, ExecutionPlan};
2929
use std::sync::Arc;
3030

3131
#[test]
@@ -92,7 +92,8 @@ mod tests {
9292

9393
let grandchild_plan = generate_local_plan();
9494

95-
let child_plan = child_plan.with_new_children(vec![grandchild_plan])?;
95+
let child_plan = child_plan
96+
.replace_children(vec![grandchild_plan], ChildrenPropertiesHint::Recompute)?;
9697

9798
unsafe {
9899
// Originally the runtime is not set. We go through the unsafe casting
@@ -107,7 +108,8 @@ mod tests {
107108
assert!((*grandchild_private_data).runtime.is_none());
108109
}
109110

110-
let parent_plan = generate_local_plan().with_new_children(vec![child_plan])?;
111+
let parent_plan = generate_local_plan()
112+
.replace_children(vec![child_plan], ChildrenPropertiesHint::Recompute)?;
111113

112114
// Adding the grandchild beneath this FFI plan should get the runtime passed down.
113115
let runtime = tokio::runtime::Builder::new_current_thread()

datafusion/physical-optimizer/src/ensure_requirements/enforce_distribution.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,16 +760,19 @@ fn preserving_order_enables_streaming(
760760
return Ok(false);
761761
}
762762
// Build parent with the ordered child
763-
let with_ordered =
764-
Arc::clone(parent).with_new_children(vec![Arc::clone(ordered_child)])?;
763+
let with_ordered = with_new_children_if_necessary(
764+
Arc::clone(parent),
765+
vec![Arc::clone(ordered_child)],
766+
)?;
765767
if with_ordered.pipeline_behavior() == EmissionType::Final {
766768
// Parent is blocking even with ordering — no benefit
767769
return Ok(false);
768770
}
769771
// Build parent with an unordered child via CoalescePartitionsExec.
770772
let unordered_child: Arc<dyn ExecutionPlan> =
771773
Arc::new(CoalescePartitionsExec::new(Arc::clone(ordered_child)));
772-
let without_ordered = Arc::clone(parent).with_new_children(vec![unordered_child])?;
774+
let without_ordered =
775+
with_new_children_if_necessary(Arc::clone(parent), vec![unordered_child])?;
773776
Ok(without_ordered.pipeline_behavior() == EmissionType::Final)
774777
}
775778

datafusion/physical-optimizer/src/limit_pushdown.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ use datafusion_physical_plan::placeholder_row::PlaceholderRowExec;
7777
use datafusion_physical_plan::projection::ProjectionExec;
7878
use datafusion_physical_plan::sorts::sort_preserving_merge::SortPreservingMergeExec;
7979
use datafusion_physical_plan::statistics::{StatisticsArgs, StatisticsContext};
80-
use datafusion_physical_plan::{ExecutionPlan, ExecutionPlanProperties};
80+
use datafusion_physical_plan::{
81+
ExecutionPlan, ExecutionPlanProperties, with_new_children_if_necessary,
82+
};
8183
/// This rule inspects [`ExecutionPlan`]'s and pushes down the fetch limit from
8284
/// the parent to the child if applicable.
8385
#[derive(Default, Debug)]
@@ -403,7 +405,7 @@ pub(crate) fn pushdown_limits(
403405
.collect::<Result<_>>()?;
404406

405407
if changed {
406-
new_node.data.with_new_children(new_children)
408+
with_new_children_if_necessary(new_node.data, new_children)
407409
} else {
408410
Ok(new_node.data)
409411
}

datafusion/physical-optimizer/src/topk_repartition.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ use std::sync::Arc;
5555
use datafusion_physical_plan::coalesce_batches::CoalesceBatchesExec;
5656
use datafusion_physical_plan::repartition::RepartitionExec;
5757
use datafusion_physical_plan::sorts::sort::SortExec;
58-
use datafusion_physical_plan::{ExecutionPlan, Partitioning};
58+
use datafusion_physical_plan::{
59+
ExecutionPlan, Partitioning, with_new_children_if_necessary,
60+
};
5961

6062
/// A physical optimizer rule that pushes TopK (Sort with fetch) past
6163
/// hash repartition when the partition key is a prefix of the sort key.
@@ -151,7 +153,7 @@ impl PhysicalOptimizerRule for TopKRepartition {
151153

152154
// Rebuild the tree above the repartition
153155
let new_sort_input = if let Some(parent) = repart_parent {
154-
parent.with_new_children(vec![new_repartition])?
156+
with_new_children_if_necessary(parent, vec![new_repartition])?
155157
} else {
156158
new_repartition
157159
};

datafusion/physical-optimizer/src/window_topn.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ use datafusion_common::{Result, ScalarValue};
5858
use datafusion_expr::Operator;
5959
use datafusion_physical_expr::expressions::{BinaryExpr, Column, Literal};
6060
use datafusion_physical_expr::window::StandardWindowExpr;
61-
use datafusion_physical_plan::ExecutionPlan;
6261
use datafusion_physical_plan::filter::FilterExec;
6362
use datafusion_physical_plan::projection::ProjectionExec;
6463
use datafusion_physical_plan::repartition::RepartitionExec;
@@ -67,6 +66,7 @@ use datafusion_physical_plan::sorts::partitioned_topk::{
6766
};
6867
use datafusion_physical_plan::sorts::sort::SortExec;
6968
use datafusion_physical_plan::windows::{BoundedWindowAggExec, WindowUDFExpr};
69+
use datafusion_physical_plan::{ExecutionPlan, with_new_children_if_necessary};
7070

7171
/// Physical optimizer rule that converts per-partition `ROW_NUMBER` and
7272
/// `RANK` top-K queries into a more efficient plan using
@@ -192,13 +192,13 @@ impl WindowTopN {
192192
.ok()?;
193193

194194
// Step 8: Rebuild window with new child
195-
let mut result = window_exec
196-
.with_new_children(vec![Arc::new(partitioned_topk)])
197-
.ok()?;
195+
let mut result =
196+
with_new_children_if_necessary(window_exec, vec![Arc::new(partitioned_topk)])
197+
.ok()?;
198198

199199
// Step 9: Rebuild intermediate nodes (ProjectionExec/RepartitionExec)
200200
for node in intermediates.into_iter().rev() {
201-
result = node.with_new_children(vec![result]).ok()?;
201+
result = with_new_children_if_necessary(node, vec![result]).ok()?;
202202
}
203203

204204
Some(result)

datafusion/physical-plan/src/async_func.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ impl AsyncFuncExec {
297297
node: &datafusion_proto_models::protobuf::PhysicalPlanNode,
298298
ctx: &crate::proto::ExecutionPlanDecodeCtx<'_>,
299299
) -> Result<Arc<dyn ExecutionPlan>> {
300+
use datafusion_common::assert_eq_or_internal_err;
300301
use datafusion_proto_models::protobuf;
301302
let async_func = crate::expect_plan_variant!(
302303
node,

datafusion/physical-plan/src/buffer.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::statistics::{ChildStats, StatisticsArgs};
2828
use crate::stream::RecordBatchStreamAdapter;
2929
use crate::{
3030
ChildrenPropertiesHint, DisplayAs, DisplayFormatType, ExecutionPlan, PlanProperties,
31-
SortOrderPushdownResult, validate_child_count,
31+
SortOrderPushdownResult, validate_child_count, with_new_children_if_necessary,
3232
};
3333
use arrow::array::RecordBatch;
3434
use datafusion_common::config::ConfigOptions;
@@ -273,9 +273,10 @@ impl ExecutionPlan for BufferExec {
273273
projection: &ProjectionExec,
274274
) -> Result<Option<Arc<dyn ExecutionPlan>>> {
275275
match self.input.try_swapping_with_projection(projection)? {
276-
Some(new_input) => Ok(Some(
277-
Arc::new(self.clone()).with_new_children(vec![new_input])?,
278-
)),
276+
Some(new_input) => Ok(Some(with_new_children_if_necessary(
277+
Arc::new(self.clone()),
278+
vec![new_input],
279+
)?)),
279280
None => Ok(None),
280281
}
281282
}

0 commit comments

Comments
 (0)