Skip to content

Commit 2f73558

Browse files
authored
Fix indented display for multi-child nodes (#358)
1 parent 5c5a0bb commit 2f73558

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

datafusion/src/physical_plan/display.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ impl<'a, 'b> ExecutionPlanVisitor for IndentVisitor<'a, 'b> {
8787
self.indent += 1;
8888
Ok(true)
8989
}
90+
91+
fn post_visit(&mut self, _plan: &dyn ExecutionPlan) -> Result<bool, Self::Error> {
92+
self.indent -= 1;
93+
Ok(true)
94+
}
9095
}

datafusion/tests/sql.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,3 +2989,52 @@ async fn test_physical_plan_display_indent() {
29892989
expected, actual
29902990
);
29912991
}
2992+
2993+
#[tokio::test]
2994+
async fn test_physical_plan_display_indent_multi_children() {
2995+
// Hard code concurrency as it appears in the RepartitionExec output
2996+
let config = ExecutionConfig::new().with_concurrency(3);
2997+
let mut ctx = ExecutionContext::with_config(config);
2998+
// ensure indenting works for nodes with multiple children
2999+
register_aggregate_csv(&mut ctx).unwrap();
3000+
let sql = "SELECT c1 \
3001+
FROM (select c1 from aggregate_test_100)\
3002+
JOIN\
3003+
(select c1 as c2 from aggregate_test_100)\
3004+
ON c1=c2\
3005+
";
3006+
3007+
let plan = ctx.create_logical_plan(&sql).unwrap();
3008+
let plan = ctx.optimize(&plan).unwrap();
3009+
3010+
let physical_plan = ctx.create_physical_plan(&plan).unwrap();
3011+
let expected = vec![
3012+
"ProjectionExec: expr=[c1]",
3013+
" CoalesceBatchesExec: target_batch_size=4096",
3014+
" HashJoinExec: mode=Partitioned, join_type=Inner, on=[(\"c1\", \"c2\")]",
3015+
" CoalesceBatchesExec: target_batch_size=4096",
3016+
" RepartitionExec: partitioning=Hash([Column { name: \"c1\" }], 3)",
3017+
" ProjectionExec: expr=[c1]",
3018+
" RepartitionExec: partitioning=RoundRobinBatch(3)",
3019+
" CsvExec: source=Path(ARROW_TEST_DATA/csv/aggregate_test_100.csv: [ARROW_TEST_DATA/csv/aggregate_test_100.csv]), has_header=true",
3020+
" CoalesceBatchesExec: target_batch_size=4096",
3021+
" RepartitionExec: partitioning=Hash([Column { name: \"c2\" }], 3)",
3022+
" ProjectionExec: expr=[c1 as c2]",
3023+
" RepartitionExec: partitioning=RoundRobinBatch(3)",
3024+
" CsvExec: source=Path(ARROW_TEST_DATA/csv/aggregate_test_100.csv: [ARROW_TEST_DATA/csv/aggregate_test_100.csv]), has_header=true",
3025+
];
3026+
3027+
let data_path = arrow::util::test_util::arrow_test_data();
3028+
let actual = format!("{}", displayable(physical_plan.as_ref()).indent())
3029+
.trim()
3030+
.lines()
3031+
// normalize paths
3032+
.map(|s| s.replace(&data_path, "ARROW_TEST_DATA"))
3033+
.collect::<Vec<_>>();
3034+
3035+
assert_eq!(
3036+
expected, actual,
3037+
"expected:\n{:#?}\nactual:\n\n{:#?}\n",
3038+
expected, actual
3039+
);
3040+
}

0 commit comments

Comments
 (0)