1616// under the License.
1717
1818use std:: collections:: HashSet ;
19+ use std:: ops:: ControlFlow ;
1920use std:: sync:: Arc ;
2021
2122use crate :: planner:: { ContextProvider , PlannerContext , SqlToRel } ;
@@ -28,7 +29,7 @@ use crate::utils::{
2829
2930use datafusion_common:: error:: DataFusionErrorBuilder ;
3031use datafusion_common:: tree_node:: { TreeNode , TreeNodeRecursion } ;
31- use datafusion_common:: { not_impl_err, plan_err, Result } ;
32+ use datafusion_common:: { not_impl_err, plan_err, DataFusionError , Result } ;
3233use datafusion_common:: { RecursionUnnestOption , UnnestOptions } ;
3334use datafusion_expr:: expr:: { Alias , PlannedReplaceSelectItem , WildcardOptions } ;
3435use datafusion_expr:: expr_rewriter:: {
@@ -45,8 +46,8 @@ use datafusion_expr::{
4546
4647use indexmap:: IndexMap ;
4748use sqlparser:: ast:: {
48- Distinct , Expr as SQLExpr , GroupByExpr , NamedWindowExpr , OrderBy ,
49- SelectItemQualifiedWildcardKind , WildcardAdditionalOptions , WindowType ,
49+ visit_expressions_mut , Distinct , Expr as SQLExpr , GroupByExpr , NamedWindowExpr ,
50+ OrderBy , SelectItemQualifiedWildcardKind , WildcardAdditionalOptions , WindowType ,
5051} ;
5152use sqlparser:: ast:: { NamedWindowDefinition , Select , SelectItem , TableWithJoins } ;
5253
@@ -891,29 +892,42 @@ fn match_window_definitions(
891892 named_windows : & [ NamedWindowDefinition ] ,
892893) -> Result < ( ) > {
893894 for proj in projection. iter_mut ( ) {
894- if let SelectItem :: ExprWithAlias {
895- expr : SQLExpr :: Function ( f) ,
896- alias : _,
897- }
898- | SelectItem :: UnnamedExpr ( SQLExpr :: Function ( f) ) = proj
895+ if let SelectItem :: ExprWithAlias { expr, alias : _ }
896+ | SelectItem :: UnnamedExpr ( expr) = proj
899897 {
900- for NamedWindowDefinition ( window_ident, window_expr) in named_windows. iter ( ) {
901- if let Some ( WindowType :: NamedWindow ( ident) ) = & f. over {
902- if ident. eq ( window_ident) {
903- f. over = Some ( match window_expr {
904- NamedWindowExpr :: NamedWindow ( ident) => {
905- WindowType :: NamedWindow ( ident. clone ( ) )
906- }
907- NamedWindowExpr :: WindowSpec ( spec) => {
908- WindowType :: WindowSpec ( spec. clone ( ) )
898+ let mut err = None ;
899+ visit_expressions_mut ( expr, |expr| {
900+ if let SQLExpr :: Function ( f) = expr {
901+ if let Some ( WindowType :: NamedWindow ( _) ) = & f. over {
902+ for NamedWindowDefinition ( window_ident, window_expr) in
903+ named_windows
904+ {
905+ if let Some ( WindowType :: NamedWindow ( ident) ) = & f. over {
906+ if ident. eq ( window_ident) {
907+ f. over = Some ( match window_expr {
908+ NamedWindowExpr :: NamedWindow ( ident) => {
909+ WindowType :: NamedWindow ( ident. clone ( ) )
910+ }
911+ NamedWindowExpr :: WindowSpec ( spec) => {
912+ WindowType :: WindowSpec ( spec. clone ( ) )
913+ }
914+ } )
915+ }
909916 }
910- } )
917+ }
918+ // All named windows must be defined with a WindowSpec.
919+ if let Some ( WindowType :: NamedWindow ( ident) ) = & f. over {
920+ err = Some ( DataFusionError :: Plan ( format ! (
921+ "The window {ident} is not defined!"
922+ ) ) ) ;
923+ return ControlFlow :: Break ( ( ) ) ;
924+ }
911925 }
912926 }
913- }
914- // All named windows must be defined with a WindowSpec.
915- if let Some ( WindowType :: NamedWindow ( ident ) ) = & f . over {
916- return plan_err ! ( "The window {ident} is not defined!" ) ;
927+ ControlFlow :: Continue ( ( ) )
928+ } ) ;
929+ if let Some ( err ) = err {
930+ return Err ( err ) ;
917931 }
918932 }
919933 }
0 commit comments