@@ -21,7 +21,6 @@ use crate::AnalyzerRule;
2121use datafusion_common:: config:: ConfigOptions ;
2222use datafusion_common:: tree_node:: { Transformed , TransformedResult } ;
2323use datafusion_common:: { Column , Result } ;
24- use datafusion_expr:: builder:: validate_unique_names;
2524use datafusion_expr:: expr:: PlannedReplaceSelectItem ;
2625use datafusion_expr:: utils:: {
2726 expand_qualified_wildcard, expand_wildcard, find_base_plan,
@@ -53,12 +52,16 @@ impl AnalyzerRule for ExpandWildcardRule {
5352
5453fn expand_internal ( plan : LogicalPlan ) -> Result < Transformed < LogicalPlan > > {
5554 match plan {
56- LogicalPlan :: Projection ( Projection { expr, input, .. } ) => {
57- let projected_expr = expand_exprlist ( & input, expr) ?;
58- Ok ( Transformed :: yes (
59- Projection :: try_new ( projected_expr, Arc :: clone ( & input) )
60- . map ( LogicalPlan :: Projection ) ?,
61- ) )
55+ LogicalPlan :: Projection ( projection) => {
56+ let projected_expr =
57+ expand_exprlist ( & projection. input , projection. expr . clone ( ) ) ?;
58+ match projected_expr {
59+ None => Ok ( Transformed :: no ( LogicalPlan :: Projection ( projection) ) ) ,
60+ Some ( projected_expr) => Ok ( Transformed :: yes (
61+ Projection :: try_new ( projected_expr, Arc :: clone ( & projection. input ) )
62+ . map ( LogicalPlan :: Projection ) ?,
63+ ) ) ,
64+ }
6265 }
6366 // The schema of the plan should also be updated if the child plan is transformed.
6467 LogicalPlan :: SubqueryAlias ( SubqueryAlias { input, alias, .. } ) => {
@@ -68,22 +71,30 @@ fn expand_internal(plan: LogicalPlan) -> Result<Transformed<LogicalPlan>> {
6871 }
6972 LogicalPlan :: Distinct ( Distinct :: On ( distinct_on) ) => {
7073 let projected_expr =
71- expand_exprlist ( & distinct_on. input , distinct_on. select_expr ) ?;
72- validate_unique_names ( "Distinct" , projected_expr. iter ( ) ) ?;
73- Ok ( Transformed :: yes ( LogicalPlan :: Distinct ( Distinct :: On (
74- DistinctOn :: try_new (
75- distinct_on. on_expr ,
76- projected_expr,
77- distinct_on. sort_expr ,
78- distinct_on. input ,
79- ) ?,
80- ) ) ) )
74+ expand_exprlist ( & distinct_on. input , distinct_on. select_expr . clone ( ) ) ?;
75+ match projected_expr {
76+ None => Ok ( Transformed :: no ( LogicalPlan :: Distinct ( Distinct :: On (
77+ distinct_on,
78+ ) ) ) ) ,
79+ Some ( projected_expr) => Ok ( Transformed :: yes ( LogicalPlan :: Distinct (
80+ Distinct :: On ( DistinctOn :: try_new (
81+ distinct_on. on_expr ,
82+ projected_expr,
83+ distinct_on. sort_expr ,
84+ distinct_on. input ,
85+ ) ?) ,
86+ ) ) ) ,
87+ }
8188 }
8289 _ => Ok ( Transformed :: no ( plan) ) ,
8390 }
8491}
8592
86- fn expand_exprlist ( input : & LogicalPlan , expr : Vec < Expr > ) -> Result < Vec < Expr > > {
93+ fn expand_exprlist ( input : & LogicalPlan , expr : Vec < Expr > ) -> Result < Option < Vec < Expr > > > {
94+ if !expr. iter ( ) . any ( |e| matches ! ( e, Expr :: Wildcard { .. } ) ) {
95+ return Ok ( None ) ;
96+ }
97+
8798 let mut projected_expr = vec ! [ ] ;
8899 let input = find_base_plan ( input) ;
89100 for e in expr {
@@ -144,7 +155,7 @@ fn expand_exprlist(input: &LogicalPlan, expr: Vec<Expr>) -> Result<Vec<Expr>> {
144155 _ => projected_expr. push ( e) ,
145156 }
146157 }
147- Ok ( projected_expr)
158+ Ok ( Some ( projected_expr) )
148159}
149160
150161/// If there is a REPLACE statement in the projected expression in the form of
0 commit comments