@@ -374,6 +374,24 @@ fn optimize_plan(
374374 ) ?;
375375 from_plan ( plan, & plan. expressions ( ) , & [ child] )
376376 }
377+ // at a distinct, all columns are required
378+ LogicalPlan :: Distinct ( distinct) => {
379+ let new_required_columns = distinct
380+ . input
381+ . schema ( )
382+ . fields ( )
383+ . iter ( )
384+ . map ( |f| f. qualified_column ( ) )
385+ . collect ( ) ;
386+ let child = optimize_plan (
387+ _optimizer,
388+ distinct. input . as_ref ( ) ,
389+ & new_required_columns,
390+ has_projection,
391+ _config,
392+ ) ?;
393+ from_plan ( plan, & [ ] , & [ child] )
394+ }
377395 // all other nodes: Add any additional columns used by
378396 // expressions in this node to the list of required columns
379397 LogicalPlan :: Limit ( _)
@@ -392,7 +410,6 @@ fn optimize_plan(
392410 | LogicalPlan :: DropView ( _)
393411 | LogicalPlan :: SetVariable ( _)
394412 | LogicalPlan :: CrossJoin ( _)
395- | LogicalPlan :: Distinct ( _)
396413 | LogicalPlan :: Extension { .. }
397414 | LogicalPlan :: Prepare ( _) => {
398415 let expr = plan. expressions ( ) ;
@@ -1009,6 +1026,25 @@ mod tests {
10091026 Ok ( ( ) )
10101027 }
10111028
1029+ #[ test]
1030+ fn pushdown_through_distinct ( ) -> Result < ( ) > {
1031+ let table_scan = test_table_scan ( ) ?;
1032+
1033+ let plan = LogicalPlanBuilder :: from ( table_scan)
1034+ . project ( vec ! [ col( "a" ) , col( "b" ) ] ) ?
1035+ . distinct ( ) ?
1036+ . project ( vec ! [ col( "a" ) ] ) ?
1037+ . build ( ) ?;
1038+
1039+ let expected = "Projection: test.a\
1040+ \n Distinct:\
1041+ \n TableScan: test projection=[a, b]";
1042+
1043+ assert_optimized_plan_eq ( & plan, expected) ;
1044+
1045+ Ok ( ( ) )
1046+ }
1047+
10121048 fn assert_optimized_plan_eq ( plan : & LogicalPlan , expected : & str ) {
10131049 let optimized_plan = optimize ( plan) . expect ( "failed to optimize plan" ) ;
10141050 let formatted_plan = format ! ( "{optimized_plan:?}" ) ;
0 commit comments