@@ -208,6 +208,13 @@ impl From<bool> for MatchedTrailingBracket {
208208 }
209209}
210210
211+ /// Output of the [`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 {
@@ -1212,7 +1219,11 @@ impl<'a> Parser<'a> {
12121219 pub fn parse_function ( & mut self , name : ObjectName ) -> Result < Expr , ParserError > {
12131220 self . expect_token ( & Token :: LParen ) ?;
12141221 let distinct = self . parse_all_or_distinct ( ) ?. is_some ( ) ;
1215- let ( args, order_by) = self . parse_optional_args_with_orderby ( ) ?;
1222+ let ParseWindowFunctionArgsOutput {
1223+ args,
1224+ order_by,
1225+ null_treatment,
1226+ } = self . parse_window_function_args ( ) ?;
12161227 let filter = if self . dialect . supports_filter_during_aggregation ( )
12171228 && self . parse_keyword ( Keyword :: FILTER )
12181229 && self . consume_token ( & Token :: LParen )
@@ -1224,19 +1235,15 @@ impl<'a> Parser<'a> {
12241235 } else {
12251236 None
12261237 } ;
1227- let null_treatment = match self . parse_one_of_keywords ( & [ Keyword :: RESPECT , Keyword :: IGNORE ] )
1228- {
1229- Some ( keyword) => {
1230- self . expect_keyword ( Keyword :: NULLS ) ?;
12311238
1232- match keyword {
1233- Keyword :: RESPECT => Some ( NullTreatment :: RespectNulls ) ,
1234- Keyword :: IGNORE => Some ( NullTreatment :: IgnoreNulls ) ,
1235- _ => None ,
1236- }
1237- }
1238- None => None ,
1239- } ;
1239+ // Syntax for null treatment shows up either in the args list
1240+ // or after the function call, but not both.
1241+ let mut null_treatment = null_treatment . map ( NullTreatmentType :: FunctionArg ) ;
1242+ if null_treatment . is_none ( ) {
1243+ null_treatment = self
1244+ . parse_null_treatment ( ) ?
1245+ . map ( NullTreatmentType :: AfterFunction ) ;
1246+ }
12401247 let over = if self . parse_keyword ( Keyword :: OVER ) {
12411248 if self . consume_token ( & Token :: LParen ) {
12421249 let window_spec = self . parse_window_spec ( ) ?;
@@ -1259,17 +1266,37 @@ impl<'a> Parser<'a> {
12591266 } ) )
12601267 }
12611268
1269+ /// Optionally parses a null treatment clause.
1270+ fn parse_null_treatment ( & mut self ) -> Result < Option < NullTreatment > , ParserError > {
1271+ match self . parse_one_of_keywords ( & [ Keyword :: RESPECT , Keyword :: IGNORE ] ) {
1272+ Some ( keyword) => {
1273+ self . expect_keyword ( Keyword :: NULLS ) ?;
1274+
1275+ Ok ( match keyword {
1276+ Keyword :: RESPECT => Some ( NullTreatment :: RespectNulls ) ,
1277+ Keyword :: IGNORE => Some ( NullTreatment :: IgnoreNulls ) ,
1278+ _ => None ,
1279+ } )
1280+ }
1281+ None => Ok ( None ) ,
1282+ }
1283+ }
1284+
12621285 pub fn parse_time_functions ( & mut self , name : ObjectName ) -> Result < Expr , ParserError > {
1263- let ( args, order_by, special) = if self . consume_token ( & Token :: LParen ) {
1264- let ( args, order_by) = self . parse_optional_args_with_orderby ( ) ?;
1265- ( args, order_by, false )
1286+ let ( args, order_by, null_treatment, special) = if self . consume_token ( & Token :: LParen ) {
1287+ let ParseWindowFunctionArgsOutput {
1288+ args,
1289+ order_by,
1290+ null_treatment,
1291+ } = self . parse_window_function_args ( ) ?;
1292+ ( args, order_by, null_treatment, false )
12661293 } else {
1267- ( vec ! [ ] , vec ! [ ] , true )
1294+ ( vec ! [ ] , vec ! [ ] , None , true )
12681295 } ;
12691296 Ok ( Expr :: Function ( Function {
12701297 name,
12711298 args,
1272- null_treatment : None ,
1299+ null_treatment : null_treatment . map ( NullTreatmentType :: FunctionArg ) ,
12731300 filter : None ,
12741301 over : None ,
12751302 distinct : false ,
@@ -9203,11 +9230,21 @@ impl<'a> Parser<'a> {
92039230 }
92049231 }
92059232
9206- pub fn parse_optional_args_with_orderby (
9207- & mut self ,
9208- ) -> Result < ( Vec < FunctionArg > , Vec < OrderByExpr > ) , ParserError > {
9233+ /// Parses a potentially empty list of arguments to a window function
9234+ /// (including the closing parenthesis).
9235+ ///
9236+ /// Examples:
9237+ /// ```sql
9238+ /// FIRST_VALUE(x ORDER BY 1,2,3);
9239+ /// FIRST_VALUE(x IGNORE NULL);
9240+ /// ```
9241+ fn parse_window_function_args ( & mut self ) -> Result < ParseWindowFunctionArgsOutput , ParserError > {
92099242 if self . consume_token ( & Token :: RParen ) {
9210- Ok ( ( vec ! [ ] , vec ! [ ] ) )
9243+ Ok ( ParseWindowFunctionArgsOutput {
9244+ args : vec ! [ ] ,
9245+ order_by : vec ! [ ] ,
9246+ null_treatment : None ,
9247+ } )
92119248 } else {
92129249 // Snowflake permits a subquery to be passed as an argument without
92139250 // an enclosing set of parens if it's the only argument.
@@ -9219,22 +9256,34 @@ impl<'a> Parser<'a> {
92199256 self . prev_token ( ) ;
92209257 let subquery = self . parse_boxed_query ( ) ?;
92219258 self . expect_token ( & Token :: RParen ) ?;
9222- return Ok ( (
9223- vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: from( Expr :: Subquery (
9259+ return Ok ( ParseWindowFunctionArgsOutput {
9260+ args : vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: from( Expr :: Subquery (
92249261 subquery,
92259262 ) ) ) ] ,
9226- vec ! [ ] ,
9227- ) ) ;
9263+ order_by : vec ! [ ] ,
9264+ null_treatment : None ,
9265+ } ) ;
92289266 }
92299267
92309268 let args = self . parse_comma_separated ( Parser :: parse_function_args) ?;
92319269 let order_by = if self . parse_keywords ( & [ Keyword :: ORDER , Keyword :: BY ] ) {
92329270 self . parse_comma_separated ( Parser :: parse_order_by_expr) ?
92339271 } else {
9234- vec ! [ ]
9272+ Default :: default ( )
9273+ } ;
9274+
9275+ let null_treatment = if self . dialect . supports_window_function_null_treatment_arg ( ) {
9276+ self . parse_null_treatment ( ) ?
9277+ } else {
9278+ None
92359279 } ;
9280+
92369281 self . expect_token ( & Token :: RParen ) ?;
9237- Ok ( ( args, order_by) )
9282+ Ok ( ParseWindowFunctionArgsOutput {
9283+ args,
9284+ order_by,
9285+ null_treatment,
9286+ } )
92389287 }
92399288 }
92409289
0 commit comments