@@ -468,6 +468,44 @@ def test_invalid_window_frame(units, start_bound, end_bound):
468468 WindowFrame (units , start_bound , end_bound )
469469
470470
471+ def test_window_frame_defaults_match_postgres (partitioned_df ):
472+ # ref: https://github.com/apache/datafusion-python/issues/688
473+
474+ window_frame = WindowFrame ("rows" , None , None )
475+
476+ col_a = column ("a" )
477+
478+ # Using `f.window` with or without an unbounded window_frame produces the same
479+ # results. These tests are included as a regression check but can be removed when
480+ # f.window() is deprecated in favor of using the .over() approach.
481+ no_frame = f .window ("avg" , [col_a ]).alias ("no_frame" )
482+ with_frame = f .window ("avg" , [col_a ], window_frame = window_frame ).alias ("with_frame" )
483+ df_1 = partitioned_df .select (col_a , no_frame , with_frame )
484+
485+ expected = {
486+ "a" : [0 , 1 , 2 , 3 , 4 , 5 , 6 ],
487+ "no_frame" : [3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 ],
488+ "with_frame" : [3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 ],
489+ }
490+
491+ assert df_1 .sort (col_a ).to_pydict () == expected
492+
493+ # When order is not set, the default frame should be unounded preceeding to
494+ # unbounded following. When order is set, the default frame is unbounded preceeding
495+ # to current row.
496+ no_order = f .avg (col_a ).over (Window ()).alias ("over_no_order" )
497+ with_order = f .avg (col_a ).over (Window (order_by = [col_a ])).alias ("over_with_order" )
498+ df_2 = partitioned_df .select (col_a , no_order , with_order )
499+
500+ expected = {
501+ "a" : [0 , 1 , 2 , 3 , 4 , 5 , 6 ],
502+ "over_no_order" : [3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 ],
503+ "over_with_order" : [0.0 , 0.5 , 1.0 , 1.5 , 2.0 , 2.5 , 3.0 ],
504+ }
505+
506+ assert df_2 .sort (col_a ).to_pydict () == expected
507+
508+
471509def test_get_dataframe (tmp_path ):
472510 ctx = SessionContext ()
473511
0 commit comments