@@ -363,4 +363,70 @@ impl From<&FFI_SortOptions> for SortOptions {
363363}
364364
365365#[ cfg( test) ]
366- mod tests { }
366+ #[ cfg( feature = "integration-tests" ) ]
367+ mod tests {
368+ use crate :: tests:: create_record_batch;
369+ use crate :: udwf:: { FFI_WindowUDF , ForeignWindowUDF } ;
370+ use arrow:: array:: { create_array, ArrayRef } ;
371+ use datafusion:: functions_window:: lead_lag:: { lag_udwf, WindowShift } ;
372+ use datafusion:: logical_expr:: expr:: Sort ;
373+ use datafusion:: logical_expr:: { col, ExprFunctionExt , WindowUDF , WindowUDFImpl } ;
374+ use datafusion:: prelude:: SessionContext ;
375+ use std:: sync:: Arc ;
376+
377+ fn create_test_foreign_udwf (
378+ original_udwf : impl WindowUDFImpl + ' static ,
379+ ) -> datafusion:: common:: Result < WindowUDF > {
380+ let original_udwf = Arc :: new ( WindowUDF :: from ( original_udwf) ) ;
381+
382+ let local_udwf: FFI_WindowUDF = Arc :: clone ( & original_udwf) . into ( ) ;
383+
384+ let foreign_udwf: ForeignWindowUDF = ( & local_udwf) . try_into ( ) ?;
385+ Ok ( foreign_udwf. into ( ) )
386+ }
387+
388+ #[ test]
389+ fn test_round_trip_udwf ( ) -> datafusion:: common:: Result < ( ) > {
390+ let original_udwf = lag_udwf ( ) ;
391+ let original_name = original_udwf. name ( ) . to_owned ( ) ;
392+
393+ // Convert to FFI format
394+ let local_udwf: FFI_WindowUDF = Arc :: clone ( & original_udwf) . into ( ) ;
395+
396+ // Convert back to native format
397+ let foreign_udwf: ForeignWindowUDF = ( & local_udwf) . try_into ( ) ?;
398+ let foreign_udwf: WindowUDF = foreign_udwf. into ( ) ;
399+
400+ assert_eq ! ( original_name, foreign_udwf. name( ) ) ;
401+ Ok ( ( ) )
402+ }
403+
404+ #[ tokio:: test]
405+ async fn test_lag_udwf ( ) -> datafusion:: common:: Result < ( ) > {
406+ let udwf = create_test_foreign_udwf ( WindowShift :: lag ( ) ) ?;
407+
408+ let ctx = SessionContext :: default ( ) ;
409+ let df = ctx. read_batch ( create_record_batch ( -5 , 5 ) ) ?;
410+
411+ let df = df. select ( vec ! [
412+ col( "a" ) ,
413+ udwf. call( vec![ col( "a" ) ] )
414+ . order_by( vec![ Sort :: new( col( "a" ) , true , true ) ] )
415+ . build( )
416+ . unwrap( )
417+ . alias( "lag_a" ) ,
418+ ] ) ?;
419+
420+ df. clone ( ) . show ( ) . await ?;
421+
422+ let result = df. collect ( ) . await ?;
423+ let expected =
424+ create_array ! ( Int32 , [ None , Some ( -5 ) , Some ( -4 ) , Some ( -3 ) , Some ( -2 ) ] )
425+ as ArrayRef ;
426+
427+ assert_eq ! ( result. len( ) , 1 ) ;
428+ assert_eq ! ( result[ 0 ] . column( 1 ) , & expected) ;
429+
430+ Ok ( ( ) )
431+ }
432+ }
0 commit comments