@@ -219,17 +219,17 @@ impl TryFrom<&FFI_ExecutionPlan> for ForeignExecutionPlan {
219
219
let properties: PlanProperties = ( plan. properties ) ( plan) . try_into ( ) ?;
220
220
221
221
let children_rvec = ( plan. children ) ( plan) ;
222
- let children: Result < Vec < _ > > = children_rvec
222
+ let children = children_rvec
223
223
. iter ( )
224
224
. map ( ForeignExecutionPlan :: try_from)
225
225
. map ( |child| child. map ( |c| Arc :: new ( c) as Arc < dyn ExecutionPlan > ) )
226
- . collect ( ) ;
226
+ . collect :: < Result < Vec < _ > > > ( ) ? ;
227
227
228
228
Ok ( Self {
229
229
name,
230
230
plan : plan. clone ( ) ,
231
231
properties,
232
- children : children? ,
232
+ children,
233
233
} )
234
234
}
235
235
}
@@ -281,6 +281,7 @@ impl ExecutionPlan for ForeignExecutionPlan {
281
281
282
282
#[ cfg( test) ]
283
283
mod tests {
284
+ use arrow:: datatypes:: { DataType , Field , Schema } ;
284
285
use datafusion:: {
285
286
physical_plan:: {
286
287
execution_plan:: { Boundedness , EmissionType } ,
@@ -294,6 +295,7 @@ mod tests {
294
295
#[ derive( Debug ) ]
295
296
pub struct EmptyExec {
296
297
props : PlanProperties ,
298
+ children : Vec < Arc < dyn ExecutionPlan > > ,
297
299
}
298
300
299
301
impl EmptyExec {
@@ -305,6 +307,7 @@ mod tests {
305
307
EmissionType :: Incremental ,
306
308
Boundedness :: Bounded ,
307
309
) ,
310
+ children : Vec :: default ( ) ,
308
311
}
309
312
}
310
313
}
@@ -333,14 +336,17 @@ mod tests {
333
336
}
334
337
335
338
fn children ( & self ) -> Vec < & Arc < dyn ExecutionPlan > > {
336
- vec ! [ ]
339
+ self . children . iter ( ) . collect ( )
337
340
}
338
341
339
342
fn with_new_children (
340
343
self : Arc < Self > ,
341
- _ : Vec < Arc < dyn ExecutionPlan > > ,
344
+ children : Vec < Arc < dyn ExecutionPlan > > ,
342
345
) -> Result < Arc < dyn ExecutionPlan > > {
343
- unimplemented ! ( )
346
+ Ok ( Arc :: new ( EmptyExec {
347
+ props : self . props . clone ( ) ,
348
+ children,
349
+ } ) )
344
350
}
345
351
346
352
fn execute (
@@ -358,7 +364,6 @@ mod tests {
358
364
359
365
#[ test]
360
366
fn test_round_trip_ffi_execution_plan ( ) -> Result < ( ) > {
361
- use arrow:: datatypes:: { DataType , Field , Schema } ;
362
367
let schema =
363
368
Arc :: new ( Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Float32 , false ) ] ) ) ;
364
369
let ctx = SessionContext :: new ( ) ;
@@ -372,6 +377,49 @@ mod tests {
372
377
373
378
assert ! ( original_name == foreign_plan. name( ) ) ;
374
379
380
+ let display = datafusion:: physical_plan:: display:: DisplayableExecutionPlan :: new (
381
+ & foreign_plan,
382
+ ) ;
383
+
384
+ let buf = display. one_line ( ) . to_string ( ) ;
385
+ assert_eq ! ( buf. trim( ) , "FFI_ExecutionPlan(number_of_children=0)" ) ;
386
+
387
+ Ok ( ( ) )
388
+ }
389
+
390
+ #[ test]
391
+ fn test_ffi_execution_plan_children ( ) -> Result < ( ) > {
392
+ let schema =
393
+ Arc :: new ( Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Float32 , false ) ] ) ) ;
394
+ let ctx = SessionContext :: new ( ) ;
395
+
396
+ // Version 1: Adding child to the foreign plan
397
+ let child_plan = Arc :: new ( EmptyExec :: new ( Arc :: clone ( & schema) ) ) ;
398
+ let child_local = FFI_ExecutionPlan :: new ( child_plan, ctx. task_ctx ( ) , None ) ;
399
+ let child_foreign = Arc :: new ( ForeignExecutionPlan :: try_from ( & child_local) ?) ;
400
+
401
+ let parent_plan = Arc :: new ( EmptyExec :: new ( Arc :: clone ( & schema) ) ) ;
402
+ let parent_local = FFI_ExecutionPlan :: new ( parent_plan, ctx. task_ctx ( ) , None ) ;
403
+ let parent_foreign = Arc :: new ( ForeignExecutionPlan :: try_from ( & parent_local) ?) ;
404
+
405
+ assert_eq ! ( parent_foreign. children( ) . len( ) , 0 ) ;
406
+ assert_eq ! ( child_foreign. children( ) . len( ) , 0 ) ;
407
+
408
+ let parent_foreign = parent_foreign. with_new_children ( vec ! [ child_foreign] ) ?;
409
+ assert_eq ! ( parent_foreign. children( ) . len( ) , 1 ) ;
410
+
411
+ // Version 2: Adding child to the local plan
412
+ let child_plan = Arc :: new ( EmptyExec :: new ( Arc :: clone ( & schema) ) ) ;
413
+ let child_local = FFI_ExecutionPlan :: new ( child_plan, ctx. task_ctx ( ) , None ) ;
414
+ let child_foreign = Arc :: new ( ForeignExecutionPlan :: try_from ( & child_local) ?) ;
415
+
416
+ let parent_plan = Arc :: new ( EmptyExec :: new ( Arc :: clone ( & schema) ) ) ;
417
+ let parent_plan = parent_plan. with_new_children ( vec ! [ child_foreign] ) ?;
418
+ let parent_local = FFI_ExecutionPlan :: new ( parent_plan, ctx. task_ctx ( ) , None ) ;
419
+ let parent_foreign = Arc :: new ( ForeignExecutionPlan :: try_from ( & parent_local) ?) ;
420
+
421
+ assert_eq ! ( parent_foreign. children( ) . len( ) , 1 ) ;
422
+
375
423
Ok ( ( ) )
376
424
}
377
425
}
0 commit comments