@@ -208,6 +208,13 @@ impl From<bool> for MatchedTrailingBracket {
208208 }
209209}
210210
211+ /// Output of the [`Parser::parse_window_function_args`] function.
212+ struct ParseWindowFunctionArgsOutput {
213+ args : Vec < FunctionArg > ,
214+ order_by : Vec < OrderByExpr > ,
215+ null_treatment : Option < NullTreatment > ,
216+ }
217+
211218/// Options that control how the [`Parser`] parses SQL text
212219#[ derive( Debug , Clone , PartialEq , Eq ) ]
213220pub struct ParserOptions {
@@ -1229,7 +1236,11 @@ impl<'a> Parser<'a> {
12291236 pub fn parse_function ( & mut self , name : ObjectName ) -> Result < Expr , ParserError > {
12301237 self . expect_token ( & Token :: LParen ) ?;
12311238 let distinct = self . parse_all_or_distinct ( ) ?. is_some ( ) ;
1232- let ( args, order_by) = self . parse_optional_args_with_orderby ( ) ?;
1239+ let ParseWindowFunctionArgsOutput {
1240+ args,
1241+ order_by,
1242+ null_treatment,
1243+ } = self . parse_window_function_args ( ) ?;
12331244 let filter = if self . dialect . supports_filter_during_aggregation ( )
12341245 && self . parse_keyword ( Keyword :: FILTER )
12351246 && self . consume_token ( & Token :: LParen )
@@ -1241,19 +1252,15 @@ impl<'a> Parser<'a> {
12411252 } else {
12421253 None
12431254 } ;
1244- let null_treatment = match self . parse_one_of_keywords ( & [ Keyword :: RESPECT , Keyword :: IGNORE ] )
1245- {
1246- Some ( keyword) => {
1247- self . expect_keyword ( Keyword :: NULLS ) ?;
12481255
1249- match keyword {
1250- Keyword :: RESPECT => Some ( NullTreatment :: RespectNulls ) ,
1251- Keyword :: IGNORE => Some ( NullTreatment :: IgnoreNulls ) ,
1252- _ => None ,
1253- }
1254- }
1255- None => None ,
1256- } ;
1256+ // Syntax for null treatment shows up either in the args list
1257+ // or after the function call, but not both.
1258+ let mut null_treatment = null_treatment . map ( NullTreatmentType :: FunctionArg ) ;
1259+ if null_treatment . is_none ( ) {
1260+ null_treatment = self
1261+ . parse_null_treatment ( ) ?
1262+ . map ( NullTreatmentType :: AfterFunction ) ;
1263+ }
12571264 let over = if self . parse_keyword ( Keyword :: OVER ) {
12581265 if self . consume_token ( & Token :: LParen ) {
12591266 let window_spec = self . parse_window_spec ( ) ?;
@@ -1276,17 +1283,37 @@ impl<'a> Parser<'a> {
12761283 } ) )
12771284 }
12781285
1286+ /// Optionally parses a null treatment clause.
1287+ fn parse_null_treatment ( & mut self ) -> Result < Option < NullTreatment > , ParserError > {
1288+ match self . parse_one_of_keywords ( & [ Keyword :: RESPECT , Keyword :: IGNORE ] ) {
1289+ Some ( keyword) => {
1290+ self . expect_keyword ( Keyword :: NULLS ) ?;
1291+
1292+ Ok ( match keyword {
1293+ Keyword :: RESPECT => Some ( NullTreatment :: RespectNulls ) ,
1294+ Keyword :: IGNORE => Some ( NullTreatment :: IgnoreNulls ) ,
1295+ _ => None ,
1296+ } )
1297+ }
1298+ None => Ok ( None ) ,
1299+ }
1300+ }
1301+
12791302 pub fn parse_time_functions ( & mut self , name : ObjectName ) -> Result < Expr , ParserError > {
1280- let ( args, order_by, special) = if self . consume_token ( & Token :: LParen ) {
1281- let ( args, order_by) = self . parse_optional_args_with_orderby ( ) ?;
1282- ( args, order_by, false )
1303+ let ( args, order_by, null_treatment, special) = if self . consume_token ( & Token :: LParen ) {
1304+ let ParseWindowFunctionArgsOutput {
1305+ args,
1306+ order_by,
1307+ null_treatment,
1308+ } = self . parse_window_function_args ( ) ?;
1309+ ( args, order_by, null_treatment, false )
12831310 } else {
1284- ( vec ! [ ] , vec ! [ ] , true )
1311+ ( vec ! [ ] , vec ! [ ] , None , true )
12851312 } ;
12861313 Ok ( Expr :: Function ( Function {
12871314 name,
12881315 args,
1289- null_treatment : None ,
1316+ null_treatment : null_treatment . map ( NullTreatmentType :: FunctionArg ) ,
12901317 filter : None ,
12911318 over : None ,
12921319 distinct : false ,
@@ -9326,11 +9353,21 @@ impl<'a> Parser<'a> {
93269353 }
93279354 }
93289355
9329- pub fn parse_optional_args_with_orderby (
9330- & mut self ,
9331- ) -> Result < ( Vec < FunctionArg > , Vec < OrderByExpr > ) , ParserError > {
9356+ /// Parses a potentially empty list of arguments to a window function
9357+ /// (including the closing parenthesis).
9358+ ///
9359+ /// Examples:
9360+ /// ```sql
9361+ /// FIRST_VALUE(x ORDER BY 1,2,3);
9362+ /// FIRST_VALUE(x IGNORE NULL);
9363+ /// ```
9364+ fn parse_window_function_args ( & mut self ) -> Result < ParseWindowFunctionArgsOutput , ParserError > {
93329365 if self . consume_token ( & Token :: RParen ) {
9333- Ok ( ( vec ! [ ] , vec ! [ ] ) )
9366+ Ok ( ParseWindowFunctionArgsOutput {
9367+ args : vec ! [ ] ,
9368+ order_by : vec ! [ ] ,
9369+ null_treatment : None ,
9370+ } )
93349371 } else {
93359372 // Snowflake permits a subquery to be passed as an argument without
93369373 // an enclosing set of parens if it's the only argument.
@@ -9342,22 +9379,34 @@ impl<'a> Parser<'a> {
93429379 self . prev_token ( ) ;
93439380 let subquery = self . parse_boxed_query ( ) ?;
93449381 self . expect_token ( & Token :: RParen ) ?;
9345- return Ok ( (
9346- vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: from( Expr :: Subquery (
9382+ return Ok ( ParseWindowFunctionArgsOutput {
9383+ args : vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: from( Expr :: Subquery (
93479384 subquery,
93489385 ) ) ) ] ,
9349- vec ! [ ] ,
9350- ) ) ;
9386+ order_by : vec ! [ ] ,
9387+ null_treatment : None ,
9388+ } ) ;
93519389 }
93529390
93539391 let args = self . parse_comma_separated ( Parser :: parse_function_args) ?;
93549392 let order_by = if self . parse_keywords ( & [ Keyword :: ORDER , Keyword :: BY ] ) {
93559393 self . parse_comma_separated ( Parser :: parse_order_by_expr) ?
93569394 } else {
9357- vec ! [ ]
9395+ Default :: default ( )
9396+ } ;
9397+
9398+ let null_treatment = if self . dialect . supports_window_function_null_treatment_arg ( ) {
9399+ self . parse_null_treatment ( ) ?
9400+ } else {
9401+ None
93589402 } ;
9403+
93599404 self . expect_token ( & Token :: RParen ) ?;
9360- Ok ( ( args, order_by) )
9405+ Ok ( ParseWindowFunctionArgsOutput {
9406+ args,
9407+ order_by,
9408+ null_treatment,
9409+ } )
93619410 }
93629411 }
93639412
0 commit comments