(extension_other_hooks)=
Two hooks contribute things that are neither data nor functions: a rewrite pass over physical plans, and typed entries in the session config. Both take no argument and both are implemented in datafusion-ffi-example.
__datafusion_physical_optimizer_rule__ contributes a rule that rewrites physical plans, installed with {py:meth}~datafusion.SessionContext.add_physical_optimizer_rule. Reach for this rather than a {doc}query planner <query-planners> when you want to adjust the plan DataFusion produced rather than produce it yourself — it is much the smaller commitment, and rules accumulate where planners nest.
fn __datafusion_physical_optimizer_rule__<'py>( &self, py: Python<'py>, ) -> PyResult<Bound<'py, PyCapsule>> { let rule: Arc<dyn PhysicalOptimizerRule + Send + Sync> = Arc::new(self.clone()); let runtime = get_tokio_runtime().handle().clone(); let ffi = FFI_PhysicalOptimizerRule::new(rule, Some(runtime)); PyCapsule::new_with_value(py, ffi, cr"datafusion_physical_optimizer_rule") }
__datafusion_extension_options__ contributes typed configuration entries that your components can read back out of the session config, installed with {py:meth}SessionConfig.with_extension <datafusion.SessionConfig.with_extension>. FFI_ExtensionOptions carries no version field, so it is one of the three components that cannot be version-checked on import.
fn __datafusion_extension_options__<'py>( &self, py: Python<'py>, ) -> PyResult<Bound<'py, PyCapsule>> { let mut config = FFI_ExtensionOptions::default(); config .add_config(self) .map_err(|e| PyRuntimeError::new_err(e.to_string()))?; PyCapsule::new_with_value(py, config, cr"datafusion_extension_options") }