@@ -2062,6 +2062,7 @@ fn parse_select_qualify() {
20622062 null_treatment: None ,
20632063 filter: None ,
20642064 over: Some ( WindowType :: WindowSpec ( WindowSpec {
2065+ window_name: None ,
20652066 partition_by: vec![ Expr :: Identifier ( Ident :: new( "p" ) ) ] ,
20662067 order_by: vec![ OrderByExpr {
20672068 expr: Expr :: Identifier ( Ident :: new( "o" ) ) ,
@@ -4122,14 +4123,18 @@ fn parse_window_functions() {
41224123 GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING) \
41234124 FROM foo";
41244125 let select = verified_only_select ( sql) ;
4125- assert_eq ! ( 7 , select. projection. len( ) ) ;
4126+
4127+ const EXPECTED_PROJ_QTY : usize = 7 ;
4128+ assert_eq ! ( EXPECTED_PROJ_QTY , select. projection. len( ) ) ;
4129+
41264130 assert_eq ! (
41274131 & Expr :: Function ( Function {
41284132 name: ObjectName ( vec![ Ident :: new( "row_number" ) ] ) ,
41294133 args: vec![ ] ,
41304134 null_treatment: None ,
41314135 filter: None ,
41324136 over: Some ( WindowType :: WindowSpec ( WindowSpec {
4137+ window_name: None ,
41334138 partition_by: vec![ ] ,
41344139 order_by: vec![ OrderByExpr {
41354140 expr: Expr :: Identifier ( Ident :: new( "dt" ) ) ,
@@ -4144,6 +4149,66 @@ fn parse_window_functions() {
41444149 } ) ,
41454150 expr_from_projection( & select. projection[ 0 ] )
41464151 ) ;
4152+
4153+ for i in 0 ..EXPECTED_PROJ_QTY {
4154+ assert ! ( matches!(
4155+ expr_from_projection( & select. projection[ i] ) ,
4156+ Expr :: Function ( Function {
4157+ over: Some ( WindowType :: WindowSpec ( WindowSpec {
4158+ window_name: None ,
4159+ ..
4160+ } ) ) ,
4161+ ..
4162+ } )
4163+ ) ) ;
4164+ }
4165+ }
4166+
4167+ #[ test]
4168+ fn parse_named_window_functions ( ) {
4169+ let supported_dialects = TestedDialects {
4170+ dialects : vec ! [
4171+ Box :: new( GenericDialect { } ) ,
4172+ Box :: new( PostgreSqlDialect { } ) ,
4173+ Box :: new( MySqlDialect { } ) ,
4174+ Box :: new( BigQueryDialect { } ) ,
4175+ ] ,
4176+ options : None ,
4177+ } ;
4178+
4179+ let sql = "SELECT row_number() OVER (w ORDER BY dt DESC), \
4180+ sum(foo) OVER (win PARTITION BY a, b ORDER BY c, d \
4181+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) \
4182+ FROM foo \
4183+ WINDOW w AS (PARTITION BY x), win AS (ORDER BY y)";
4184+ supported_dialects. verified_stmt ( sql) ;
4185+
4186+ let select = verified_only_select ( sql) ;
4187+
4188+ const EXPECTED_PROJ_QTY : usize = 2 ;
4189+ assert_eq ! ( EXPECTED_PROJ_QTY , select. projection. len( ) ) ;
4190+
4191+ const EXPECTED_WIN_NAMES : [ & str ; 2 ] = [ "w" , "win" ] ;
4192+ for ( i, win_name) in EXPECTED_WIN_NAMES . iter ( ) . enumerate ( ) {
4193+ assert ! ( matches!(
4194+ expr_from_projection( & select. projection[ i] ) ,
4195+ Expr :: Function ( Function {
4196+ over: Some ( WindowType :: WindowSpec ( WindowSpec {
4197+ window_name: Some ( Ident { value, .. } ) ,
4198+ ..
4199+ } ) ) ,
4200+ ..
4201+ } ) if value == win_name
4202+ ) ) ;
4203+ }
4204+
4205+ let sql = "SELECT \
4206+ FIRST_VALUE(x) OVER (w ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS first, \
4207+ FIRST_VALUE(x) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS last, \
4208+ SUM(y) OVER (win PARTITION BY x) AS last \
4209+ FROM EMPLOYEE \
4210+ WINDOW w AS (PARTITION BY x), win AS (w ORDER BY y)";
4211+ supported_dialects. verified_stmt ( sql) ;
41474212}
41484213
41494214#[ test]
@@ -4244,6 +4309,7 @@ fn test_parse_named_window() {
42444309 quote_style: None ,
42454310 } ,
42464311 WindowSpec {
4312+ window_name: None ,
42474313 partition_by: vec![ ] ,
42484314 order_by: vec![ OrderByExpr {
42494315 expr: Expr :: Identifier ( Ident {
@@ -4262,6 +4328,7 @@ fn test_parse_named_window() {
42624328 quote_style: None ,
42634329 } ,
42644330 WindowSpec {
4331+ window_name: None ,
42654332 partition_by: vec![ Expr :: Identifier ( Ident {
42664333 value: "C11" . to_string( ) ,
42674334 quote_style: None ,
0 commit comments