@@ -208,6 +208,13 @@ impl From<bool> for MatchedTrailingBracket {
208
208
}
209
209
}
210
210
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
+
211
218
/// Options that control how the [`Parser`] parses SQL text
212
219
#[ derive( Debug , Clone , PartialEq , Eq ) ]
213
220
pub struct ParserOptions {
@@ -1229,7 +1236,11 @@ impl<'a> Parser<'a> {
1229
1236
pub fn parse_function ( & mut self , name : ObjectName ) -> Result < Expr , ParserError > {
1230
1237
self . expect_token ( & Token :: LParen ) ?;
1231
1238
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 ( ) ?;
1233
1244
let filter = if self . dialect . supports_filter_during_aggregation ( )
1234
1245
&& self . parse_keyword ( Keyword :: FILTER )
1235
1246
&& self . consume_token ( & Token :: LParen )
@@ -1241,19 +1252,15 @@ impl<'a> Parser<'a> {
1241
1252
} else {
1242
1253
None
1243
1254
} ;
1244
- let null_treatment = match self . parse_one_of_keywords ( & [ Keyword :: RESPECT , Keyword :: IGNORE ] )
1245
- {
1246
- Some ( keyword) => {
1247
- self . expect_keyword ( Keyword :: NULLS ) ?;
1248
1255
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
+ }
1257
1264
let over = if self . parse_keyword ( Keyword :: OVER ) {
1258
1265
if self . consume_token ( & Token :: LParen ) {
1259
1266
let window_spec = self . parse_window_spec ( ) ?;
@@ -1276,17 +1283,37 @@ impl<'a> Parser<'a> {
1276
1283
} ) )
1277
1284
}
1278
1285
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
+
1279
1302
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 )
1283
1310
} else {
1284
- ( vec ! [ ] , vec ! [ ] , true )
1311
+ ( vec ! [ ] , vec ! [ ] , None , true )
1285
1312
} ;
1286
1313
Ok ( Expr :: Function ( Function {
1287
1314
name,
1288
1315
args,
1289
- null_treatment : None ,
1316
+ null_treatment : null_treatment . map ( NullTreatmentType :: FunctionArg ) ,
1290
1317
filter : None ,
1291
1318
over : None ,
1292
1319
distinct : false ,
@@ -9326,11 +9353,21 @@ impl<'a> Parser<'a> {
9326
9353
}
9327
9354
}
9328
9355
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 > {
9332
9365
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
+ } )
9334
9371
} else {
9335
9372
// Snowflake permits a subquery to be passed as an argument without
9336
9373
// an enclosing set of parens if it's the only argument.
@@ -9342,22 +9379,34 @@ impl<'a> Parser<'a> {
9342
9379
self . prev_token ( ) ;
9343
9380
let subquery = self . parse_boxed_query ( ) ?;
9344
9381
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 (
9347
9384
subquery,
9348
9385
) ) ) ] ,
9349
- vec ! [ ] ,
9350
- ) ) ;
9386
+ order_by : vec ! [ ] ,
9387
+ null_treatment : None ,
9388
+ } ) ;
9351
9389
}
9352
9390
9353
9391
let args = self . parse_comma_separated ( Parser :: parse_function_args) ?;
9354
9392
let order_by = if self . parse_keywords ( & [ Keyword :: ORDER , Keyword :: BY ] ) {
9355
9393
self . parse_comma_separated ( Parser :: parse_order_by_expr) ?
9356
9394
} 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
9358
9402
} ;
9403
+
9359
9404
self . expect_token ( & Token :: RParen ) ?;
9360
- Ok ( ( args, order_by) )
9405
+ Ok ( ParseWindowFunctionArgsOutput {
9406
+ args,
9407
+ order_by,
9408
+ null_treatment,
9409
+ } )
9361
9410
}
9362
9411
}
9363
9412
0 commit comments