fix: Check Any, not the delegating downcast, in FFI_ExecutionPlan::new's foreign-echo shortcut - #25645
fix: Check Any, not the delegating downcast, in FFI_ExecutionPlan::new's foreign-echo shortcut#25645namanjain24-sudo wants to merge 1 commit into
Conversation
…w's foreign-echo shortcut related: apache#25155 (Direction 3 only; Direction A in that issue is a separate, larger problem needing its own design discussion, so this does not close it) FFI_ExecutionPlan::new short-circuits when the incoming plan is already a ForeignExecutionPlan, handing back its original FFI handle instead of re-wrapping it. That check went through ExecutionPlan::downcast_ref, which follows downcast_delegate when a plan opts in (added in apache#22557 so a transparent wrapper can redirect public downcasts to its inner plan). Because of that, a wrapper delegating to a ForeignExecutionPlan is misclassified as being one, and the shortcut discards the wrapper, returning the plan from before it was ever applied. Switch the check to a raw Any downcast, which only matches plan's own concrete type. This narrows the shortcut without an ABI change: for a plan whose own concrete type really is ForeignExecutionPlan (which does not implement downcast_delegate), both checks already agreed, so this only changes behavior for the wrapper case.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #25645 +/- ##
==========================================
- Coverage 82.45% 82.44% -0.02%
==========================================
Files 1140 1140
Lines 436589 436650 +61
Branches 436589 436650 +61
==========================================
+ Hits 359996 360001 +5
- Misses 54838 54889 +51
- Partials 21755 21760 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@namanjain24-sudo Thanks for working on this. The constructor change looks correct, and all 120 FFI unit tests passed locally. #25717 also identifies the delegate-aware child check in pass_runtime_to_children, which remains unchanged here; the new test doesn’t exercise runtime propagation. Since #25749 covers both checks, could we coordinate the overlapping PRs and clarify which one should land? |
|
Closing in favor of #25749, which does the same |
related: #25155
This addresses only "Direction 3" (the
FFI_ExecutionPlan::newshortcut fix)from that issue, using the exact change the issue itself proposes. The issue
also covers a separate, larger problem ("Direction A") that needs its own
design discussion and is not touched here, so this should not close it.
What happened
FFI_ExecutionPlan::newshort-circuits when the incoming plan is already aForeignExecutionPlan, handing back its original FFI handle instead ofre-wrapping it:
That check goes through
ExecutionPlan::downcast_ref, which followsdowncast_delegatewhen a plan opts in (added in #22557 so a transparentwrapper can redirect public downcasts to its inner plan). A wrapper that
delegates to a
ForeignExecutionPlanis therefore misclassified as beingone, and the shortcut discards the wrapper, returning the plan from before
it was ever applied.
What changes are included in this PR
Switch the check to a raw
Anydowncast, which only matchesplan's ownconcrete type rather than what
downcast_delegateredirects to:For a plan whose own concrete type really is
ForeignExecutionPlan(whichdoes not implement
downcast_delegate), both checks agree, so this onlynarrows the shortcut for the wrapper case. No ABI change.
What is the testing strategy for this PR
datafusion/ffi/src/execution_plan.rs: a minimaldowncast_delegate-opted-in wrapper around a plan mocked as foreign (theexisting
mock_foreign_marker_idpattern already used by sibling tests inthis file) must survive
FFI_ExecutionPlan::new. Verified it failsagainst the unpatched check — the wrapper is discarded and the round trip
reports the inner plan's name instead of the wrapper's — and passes with
the fix.
cargo test -p datafusion-ffi --lib(120 tests) and every cross-libraryintegration test binary under
--features integration-tests(
ffi_execution_plan,ffi_query_planner,ffi_physical_optimizer,ffi_integration,ffi_udaf,ffi_udf,ffi_udtf,ffi_udwf,ffi_catalog,ffi_config; 31 tests), all passing.cargo fmt --checkandcargo clippy -p datafusion-ffi --all-targets --all-featuresreport nothing for the changed file.Are there any user-facing changes?
A transparent
downcast_delegatewrapper around a plan that already crossedthe
datafusion-ffiboundary is no longer silently discarded byFFI_ExecutionPlan::new. No public API changes.