1818use std:: ffi:: c_void;
1919use std:: sync:: Arc ;
2020
21- use abi_stable:: StableAbi ;
22- use abi_stable:: std_types:: { RResult , RStr } ;
2321use async_trait:: async_trait;
2422use datafusion_common:: config:: ConfigOptions ;
2523use datafusion_common:: error:: Result ;
2624use datafusion_physical_optimizer:: PhysicalOptimizerRule ;
2725use datafusion_physical_plan:: ExecutionPlan ;
26+ use stabby:: string:: String as SString ;
2827use tokio:: runtime:: Handle ;
2928
3029use crate :: config:: FFI_ConfigOptions ;
3130use crate :: execution_plan:: FFI_ExecutionPlan ;
32- use crate :: util:: FFIResult ;
33- use crate :: { df_result, rresult_return } ;
31+ use crate :: util:: { FFI_Result , FFIResult } ;
32+ use crate :: { df_result, sresult_return } ;
3433
3534/// A stable struct for sharing [`PhysicalOptimizerRule`] across FFI boundaries.
3635#[ repr( C ) ]
37- #[ derive( Debug , StableAbi ) ]
36+ #[ derive( Debug ) ]
3837pub struct FFI_PhysicalOptimizerRule {
3938 pub optimize : unsafe extern "C" fn (
4039 & Self ,
4140 plan : & FFI_ExecutionPlan ,
4241 config : FFI_ConfigOptions ,
4342 ) -> FFIResult < FFI_ExecutionPlan > ,
4443
45- pub name : unsafe extern "C" fn ( & Self ) -> RStr ,
44+ pub name : unsafe extern "C" fn ( & Self ) -> SString ,
4645
4746 pub schema_check : unsafe extern "C" fn ( & Self ) -> bool ,
4847
@@ -92,14 +91,14 @@ unsafe extern "C" fn optimize_fn_wrapper(
9291) -> FFIResult < FFI_ExecutionPlan > {
9392 let runtime = rule. runtime ( ) ;
9493 let rule = rule. inner ( ) ;
95- let plan: Arc < dyn ExecutionPlan > = rresult_return ! ( plan. try_into( ) ) ;
96- let config = rresult_return ! ( ConfigOptions :: try_from( config) ) ;
97- let optimized_plan = rresult_return ! ( rule. optimize( plan, & config) ) ;
94+ let plan: Arc < dyn ExecutionPlan > = sresult_return ! ( plan. try_into( ) ) ;
95+ let config = sresult_return ! ( ConfigOptions :: try_from( config) ) ;
96+ let optimized_plan = sresult_return ! ( rule. optimize( plan, & config) ) ;
9897
99- RResult :: ROk ( FFI_ExecutionPlan :: new ( optimized_plan, runtime) )
98+ FFI_Result :: Ok ( FFI_ExecutionPlan :: new ( optimized_plan, runtime) )
10099}
101100
102- unsafe extern "C" fn name_fn_wrapper ( rule : & FFI_PhysicalOptimizerRule ) -> RStr < ' _ > {
101+ unsafe extern "C" fn name_fn_wrapper ( rule : & FFI_PhysicalOptimizerRule ) -> SString {
103102 let rule = rule. inner ( ) ;
104103 rule. name ( ) . into ( )
105104}
@@ -153,7 +152,7 @@ impl FFI_PhysicalOptimizerRule {
153152 if let Some ( rule) = ( Arc :: clone ( & rule) as Arc < dyn std:: any:: Any > )
154153 . downcast_ref :: < ForeignPhysicalOptimizerRule > ( )
155154 {
156- return rule. 0 . clone ( ) ;
155+ return rule. rule . clone ( ) ;
157156 }
158157
159158 let private_data = Box :: new ( RulePrivateData { rule, runtime } ) ;
@@ -177,7 +176,10 @@ impl FFI_PhysicalOptimizerRule {
177176/// defined on this struct must only use the stable functions provided in
178177/// FFI_PhysicalOptimizerRule to interact with the foreign rule.
179178#[ derive( Debug ) ]
180- pub struct ForeignPhysicalOptimizerRule ( pub FFI_PhysicalOptimizerRule ) ;
179+ pub struct ForeignPhysicalOptimizerRule {
180+ name : String ,
181+ rule : FFI_PhysicalOptimizerRule ,
182+ }
181183
182184unsafe impl Send for ForeignPhysicalOptimizerRule { }
183185unsafe impl Sync for ForeignPhysicalOptimizerRule { }
@@ -188,8 +190,11 @@ impl From<&FFI_PhysicalOptimizerRule> for Arc<dyn PhysicalOptimizerRule + Send +
188190 return Arc :: clone ( rule. inner ( ) ) ;
189191 }
190192
191- Arc :: new ( ForeignPhysicalOptimizerRule ( rule. clone ( ) ) )
192- as Arc < dyn PhysicalOptimizerRule + Send + Sync >
193+ let name: String = unsafe { ( rule. name ) ( rule) . into ( ) } ;
194+ Arc :: new ( ForeignPhysicalOptimizerRule {
195+ name,
196+ rule : rule. clone ( ) ,
197+ } ) as Arc < dyn PhysicalOptimizerRule + Send + Sync >
193198 }
194199}
195200
@@ -210,16 +215,16 @@ impl PhysicalOptimizerRule for ForeignPhysicalOptimizerRule {
210215 let plan = FFI_ExecutionPlan :: new ( plan, None ) ;
211216
212217 let optimized_plan =
213- unsafe { df_result ! ( ( self . 0 . optimize) ( & self . 0 , & plan, config_options) ) ? } ;
218+ unsafe { df_result ! ( ( self . rule . optimize) ( & self . rule , & plan, config_options) ) ? } ;
214219 ( & optimized_plan) . try_into ( )
215220 }
216221
217222 fn name ( & self ) -> & str {
218- unsafe { ( self . 0 . name ) ( & self . 0 ) . as_str ( ) }
223+ & self . name
219224 }
220225
221226 fn schema_check ( & self ) -> bool {
222- unsafe { ( self . 0 . schema_check ) ( & self . 0 ) }
227+ unsafe { ( self . rule . schema_check ) ( & self . rule ) }
223228 }
224229}
225230
@@ -341,9 +346,9 @@ mod tests {
341346 let ffi_rule = FFI_PhysicalOptimizerRule :: new ( rule, None ) ;
342347 let cloned = ffi_rule. clone ( ) ;
343348
344- assert_eq ! ( unsafe { ( ffi_rule. name) ( & ffi_rule) . as_str ( ) } , unsafe {
345- ( cloned. name) ( & cloned) . as_str ( )
346- } ) ;
349+ let name1 : String = unsafe { ( ffi_rule. name ) ( & ffi_rule) . into ( ) } ;
350+ let name2 : String = unsafe { ( cloned. name ) ( & cloned) . into ( ) } ;
351+ assert_eq ! ( name1 , name2 ) ;
347352
348353 Ok ( ( ) )
349354 }
@@ -363,10 +368,8 @@ mod tests {
363368
364369 // Now wrap the foreign rule back into FFI - should not double-wrap
365370 let re_wrapped = FFI_PhysicalOptimizerRule :: new ( foreign_rule, None ) ;
366- assert_eq ! (
367- unsafe { ( re_wrapped. name) ( & re_wrapped) . as_str( ) } ,
368- "no_op_rule"
369- ) ;
371+ let name: String = unsafe { ( re_wrapped. name ) ( & re_wrapped) . into ( ) } ;
372+ assert_eq ! ( name, "no_op_rule" ) ;
370373
371374 Ok ( ( ) )
372375 }
0 commit comments