Commit 2e7b8e1
fix(physical-plan): make HashJoinExec dynamic filter pushdown idempotent (#22523)
## Which issue does this PR close?
Related to apache/datafusion-ballista#1359
## Rationale
Ballista's Adaptive Query Execution (AQE) planner re-invokes
DataFusion's full `PhysicalOptimizer` chain after every completed stage.
`FilterPushdown::new_post_optimization()` is not idempotent on plans
containing `HashJoinExec`.
In the `Post` phase, `HashJoinExec::gather_filters_for_pushdown`
unconditionally creates a new `DynamicFilterPhysicalExpr` and installs
it on the probe-side child via `with_self_filter`. After pass 1 the join
already carries a `dynamic_filter: Some(...)`, and the shared
`Arc<DynamicFilterPhysicalExpr>` is already wired into the probe-side
scan's predicate. On pass 2 a *second* dynamic filter is created and
ANDed onto the existing predicate, producing `DynamicFilter AND
DynamicFilter`. Each subsequent pass adds another duplicate, compounding
indefinitely in AQE replan loops.
## What changes are included in this PR?
- **Guard in `HashJoinExec::gather_filters_for_pushdown`**: skip
dynamic-filter creation when `self.dynamic_filter.is_some()`, meaning a
previous pass already installed one. The existing `Arc` remains valid
and correctly wired into the probe-side scan.
- **Comment** explaining why the guard is needed (AQE replan context).
- **Test** `post_phase_is_idempotent_on_hash_join` in
`tests/physical_optimizer/filter_pushdown.rs`: builds a `HashJoinExec`,
runs `FilterPushdown::new_post_optimization()` twice, and asserts
structural equality via `get_plan_string`.
## Are these changes tested?
Yes. The new test fails without the fix (plan strings diverge due to
duplicated dynamic filter predicates) and passes with it.
## Are there any user-facing changes?
No. Dynamic filter pushdown is an internal optimization; the idempotence
guard only affects re-optimization scenarios (AQE).
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent b6d4c25 commit 2e7b8e1
2 files changed
Lines changed: 46 additions & 1 deletion
File tree
- datafusion
- core/tests/physical_optimizer
- physical-plan/src/joins/hash_join
Lines changed: 39 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3269 | 3269 | | |
3270 | 3270 | | |
3271 | 3271 | | |
| 3272 | + | |
| 3273 | + | |
| 3274 | + | |
| 3275 | + | |
| 3276 | + | |
| 3277 | + | |
| 3278 | + | |
| 3279 | + | |
| 3280 | + | |
| 3281 | + | |
| 3282 | + | |
| 3283 | + | |
| 3284 | + | |
| 3285 | + | |
| 3286 | + | |
| 3287 | + | |
| 3288 | + | |
| 3289 | + | |
| 3290 | + | |
| 3291 | + | |
| 3292 | + | |
| 3293 | + | |
| 3294 | + | |
| 3295 | + | |
| 3296 | + | |
| 3297 | + | |
| 3298 | + | |
| 3299 | + | |
| 3300 | + | |
| 3301 | + | |
| 3302 | + | |
| 3303 | + | |
| 3304 | + | |
| 3305 | + | |
| 3306 | + | |
| 3307 | + | |
| 3308 | + | |
| 3309 | + | |
| 3310 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1635 | 1635 | | |
1636 | 1636 | | |
1637 | 1637 | | |
1638 | | - | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
1639 | 1644 | | |
| 1645 | + | |
1640 | 1646 | | |
1641 | 1647 | | |
1642 | 1648 | | |
| |||
0 commit comments