@@ -374,6 +374,24 @@ fn optimize_plan(
374
374
) ?;
375
375
from_plan ( plan, & plan. expressions ( ) , & [ child] )
376
376
}
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
+ }
377
395
// all other nodes: Add any additional columns used by
378
396
// expressions in this node to the list of required columns
379
397
LogicalPlan :: Limit ( _)
@@ -392,7 +410,6 @@ fn optimize_plan(
392
410
| LogicalPlan :: DropView ( _)
393
411
| LogicalPlan :: SetVariable ( _)
394
412
| LogicalPlan :: CrossJoin ( _)
395
- | LogicalPlan :: Distinct ( _)
396
413
| LogicalPlan :: Extension { .. }
397
414
| LogicalPlan :: Prepare ( _) => {
398
415
let expr = plan. expressions ( ) ;
@@ -1009,6 +1026,25 @@ mod tests {
1009
1026
Ok ( ( ) )
1010
1027
}
1011
1028
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
+
1012
1048
fn assert_optimized_plan_eq ( plan : & LogicalPlan , expected : & str ) {
1013
1049
let optimized_plan = optimize ( plan) . expect ( "failed to optimize plan" ) ;
1014
1050
let formatted_plan = format ! ( "{optimized_plan:?}" ) ;
0 commit comments