Skip to content

feat: implement PhysicalOptimizerRule in FFI crate#20451

Merged
timsaucer merged 3 commits intoapache:mainfrom
timsaucer:feat/ffi-plan-optimizer
Mar 26, 2026
Merged

feat: implement PhysicalOptimizerRule in FFI crate#20451
timsaucer merged 3 commits intoapache:mainfrom
timsaucer:feat/ffi-plan-optimizer

Conversation

@timsaucer
Copy link
Member

@timsaucer timsaucer commented Feb 20, 2026

Which issue does this PR close?

Rationale for this change

This PR is a pure addition to implement a FFI safe PhysicalOptimizerRule. With this change downstream projects, such as datafusion-python can share optimizer rules across libraries.

What changes are included in this PR?

Implement physical optimizer rule following same pattern as the rest of the FFI crate.

Are these changes tested?

Both unit and integration tests are provided.

Are there any user-facing changes?

None

@github-actions github-actions bot added documentation Improvements or additions to documentation development-process Related to development process of DataFusion logical-expr Logical plan and expressions optimizer Optimizer rules core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) catalog Related to the catalog crate common Related to common crate execution Related to the execution crate proto Related to proto crate functions Changes to functions implementation ffi Changes to the ffi crate spark labels Feb 20, 2026
@timsaucer timsaucer force-pushed the feat/ffi-plan-optimizer branch from 00ef9d6 to 5072a54 Compare February 24, 2026 21:52
@github-actions github-actions bot removed documentation Improvements or additions to documentation development-process Related to development process of DataFusion core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) common Related to common crate execution Related to the execution crate labels Feb 24, 2026
@timsaucer timsaucer force-pushed the feat/ffi-plan-optimizer branch from 5072a54 to 84331d9 Compare March 19, 2026 15:20
@github-actions github-actions bot removed logical-expr Logical plan and expressions catalog Related to the catalog crate proto Related to proto crate functions Changes to functions implementation spark labels Mar 19, 2026
@timsaucer timsaucer marked this pull request as ready for review March 19, 2026 20:23
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me -- thanks @timsaucer

I think nulling out the private_data field is important. Otherwise it is ready to go

unsafe extern "C" fn release_fn_wrapper(provider: &mut FFI_PhysicalOptimizerRule) {
let private_data =
unsafe { Box::from_raw(provider.private_data as *mut RulePrivateData) };
drop(private_data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also set private_data to null here too, similarly to

plan.private_data = std::ptr::null_mut();

///
/// [`SessionState::add_physical_optimizer_rule`]: https://docs.rs/datafusion/latest/datafusion/execution/session_state/struct.SessionState.html#method.add_physical_optimizer_rule
pub trait PhysicalOptimizerRule: Debug {
pub trait PhysicalOptimizerRule: Debug + std::any::Any {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably call this PR out as a breaking API change as now all PhysicalOptimizerRules need to implement Any.

Also, I am not sure it matters, but this isn't consistent with how the other traits in this crate use Any. The others add an as_any() function. for example:

/// Returns the file metadata as [`Any`] so that it can be downcast to a specific
/// implementation.
fn as_any(&self) -> &dyn Any;

Adding a consistent as_any method I think is still a breaking API change and I think constrains any implementation the same way, but I do think it would be better to stay consistent with the rest of DataFusion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though with some research it seems like this method might be nicer than the as_any methods we use elsewhere as it would be less likely that downstream crates need to be changed 🤔 (to add the as_any)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With regard to that, may I interest you in this PR which removes almost 1200 lines? #20812

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, now I see the relevant PR: #20812


use crate::physical_optimizer::FFI_PhysicalOptimizerRule;

/// A rule that wraps the input plan in a GlobalLimitExec with skip=0, fetch=10.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@timsaucer timsaucer force-pushed the feat/ffi-plan-optimizer branch from 6edf4c5 to a369db2 Compare March 26, 2026 10:48
@timsaucer timsaucer added this pull request to the merge queue Mar 26, 2026
Merged via the queue into apache:main with commit 4f13319 Mar 26, 2026
37 checks passed
@timsaucer timsaucer deleted the feat/ffi-plan-optimizer branch March 26, 2026 11:54
@alamb
Copy link
Contributor

alamb commented Mar 26, 2026

🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ffi Changes to the ffi crate optimizer Optimizer rules

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose PhysicalOptimizerRule via FFI

2 participants