@@ -24,6 +24,7 @@ use core::fmt;
24
24
25
25
use log:: debug;
26
26
27
+ use recursion:: RecursionCounter ;
27
28
use IsLateral :: * ;
28
29
use IsOptional :: * ;
29
30
@@ -114,6 +115,7 @@ mod recursion {
114
115
Self { remaining_depth }
115
116
}
116
117
}
118
+
117
119
impl Drop for DepthGuard {
118
120
fn drop ( & mut self ) {
119
121
let old_value = self . remaining_depth . get ( ) ;
@@ -143,8 +145,6 @@ mod recursion {
143
145
pub struct DepthGuard { }
144
146
}
145
147
146
- use recursion:: RecursionCounter ;
147
-
148
148
#[ derive( PartialEq , Eq ) ]
149
149
pub enum IsOptional {
150
150
Optional ,
@@ -995,17 +995,17 @@ impl<'a> Parser<'a> {
995
995
| Keyword :: CURRENT_USER
996
996
| Keyword :: SESSION_USER
997
997
| Keyword :: USER
998
- if dialect_of ! ( self is PostgreSqlDialect | GenericDialect ) =>
999
- {
1000
- Ok ( Expr :: Function ( Function {
1001
- name : ObjectName ( vec ! [ w. to_ident( ) ] ) ,
1002
- args : FunctionArguments :: None ,
1003
- null_treatment : None ,
1004
- filter : None ,
1005
- over : None ,
1006
- within_group : vec ! [ ] ,
1007
- } ) )
1008
- }
998
+ if dialect_of ! ( self is PostgreSqlDialect | GenericDialect ) =>
999
+ {
1000
+ Ok ( Expr :: Function ( Function {
1001
+ name : ObjectName ( vec ! [ w. to_ident( ) ] ) ,
1002
+ args : FunctionArguments :: None ,
1003
+ null_treatment : None ,
1004
+ filter : None ,
1005
+ over : None ,
1006
+ within_group : vec ! [ ] ,
1007
+ } ) )
1008
+ }
1009
1009
Keyword :: CURRENT_TIMESTAMP
1010
1010
| Keyword :: CURRENT_TIME
1011
1011
| Keyword :: CURRENT_DATE
@@ -1019,18 +1019,18 @@ impl<'a> Parser<'a> {
1019
1019
Keyword :: TRY_CAST => self . parse_cast_expr ( CastKind :: TryCast ) ,
1020
1020
Keyword :: SAFE_CAST => self . parse_cast_expr ( CastKind :: SafeCast ) ,
1021
1021
Keyword :: EXISTS
1022
- // Support parsing Databricks has a function named `exists`.
1023
- if !dialect_of ! ( self is DatabricksDialect )
1024
- || matches ! (
1022
+ // Support parsing Databricks has a function named `exists`.
1023
+ if !dialect_of ! ( self is DatabricksDialect )
1024
+ || matches ! (
1025
1025
self . peek_nth_token( 1 ) . token,
1026
1026
Token :: Word ( Word {
1027
1027
keyword: Keyword :: SELECT | Keyword :: WITH ,
1028
1028
..
1029
1029
} )
1030
1030
) =>
1031
- {
1032
- self . parse_exists_expr ( false )
1033
- }
1031
+ {
1032
+ self . parse_exists_expr ( false )
1033
+ }
1034
1034
Keyword :: EXTRACT => self . parse_extract_expr ( ) ,
1035
1035
Keyword :: CEIL => self . parse_ceil_floor_expr ( true ) ,
1036
1036
Keyword :: FLOOR => self . parse_ceil_floor_expr ( false ) ,
@@ -1047,21 +1047,21 @@ impl<'a> Parser<'a> {
1047
1047
self . parse_array_expr ( true )
1048
1048
}
1049
1049
Keyword :: ARRAY
1050
- if self . peek_token ( ) == Token :: LParen
1051
- && !dialect_of ! ( self is ClickHouseDialect | DatabricksDialect ) =>
1052
- {
1053
- self . expect_token ( & Token :: LParen ) ?;
1054
- let query = self . parse_boxed_query ( ) ?;
1055
- self . expect_token ( & Token :: RParen ) ?;
1056
- Ok ( Expr :: Function ( Function {
1057
- name : ObjectName ( vec ! [ w. to_ident( ) ] ) ,
1058
- args : FunctionArguments :: Subquery ( query) ,
1059
- filter : None ,
1060
- null_treatment : None ,
1061
- over : None ,
1062
- within_group : vec ! [ ] ,
1063
- } ) )
1064
- }
1050
+ if self . peek_token ( ) == Token :: LParen
1051
+ && !dialect_of ! ( self is ClickHouseDialect | DatabricksDialect ) =>
1052
+ {
1053
+ self . expect_token ( & Token :: LParen ) ?;
1054
+ let query = self . parse_boxed_query ( ) ?;
1055
+ self . expect_token ( & Token :: RParen ) ?;
1056
+ Ok ( Expr :: Function ( Function {
1057
+ name : ObjectName ( vec ! [ w. to_ident( ) ] ) ,
1058
+ args : FunctionArguments :: Subquery ( query) ,
1059
+ filter : None ,
1060
+ null_treatment : None ,
1061
+ over : None ,
1062
+ within_group : vec ! [ ] ,
1063
+ } ) )
1064
+ }
1065
1065
Keyword :: NOT => self . parse_not ( ) ,
1066
1066
Keyword :: MATCH if dialect_of ! ( self is MySqlDialect | GenericDialect ) => {
1067
1067
self . parse_match_against ( )
@@ -1129,13 +1129,13 @@ impl<'a> Parser<'a> {
1129
1129
Token :: SingleQuotedString ( _)
1130
1130
| Token :: DoubleQuotedString ( _)
1131
1131
| Token :: HexStringLiteral ( _)
1132
- if w. value . starts_with ( '_' ) =>
1133
- {
1134
- Ok ( Expr :: IntroducedString {
1135
- introducer : w. value ,
1136
- value : self . parse_introduced_string_value ( ) ?,
1137
- } )
1138
- }
1132
+ if w. value . starts_with ( '_' ) =>
1133
+ {
1134
+ Ok ( Expr :: IntroducedString {
1135
+ introducer : w. value ,
1136
+ value : self . parse_introduced_string_value ( ) ?,
1137
+ } )
1138
+ }
1139
1139
Token :: Arrow if self . dialect . supports_lambda_functions ( ) => {
1140
1140
self . expect_token ( & Token :: Arrow ) ?;
1141
1141
return Ok ( Expr :: Lambda ( LambdaFunction {
@@ -1222,7 +1222,7 @@ impl<'a> Parser<'a> {
1222
1222
return parser_err ! (
1223
1223
format!( "Expected identifier, found: {tok}" ) ,
1224
1224
tok. location
1225
- )
1225
+ ) ;
1226
1226
}
1227
1227
} ;
1228
1228
Ok ( Expr :: CompositeAccess {
@@ -1528,19 +1528,23 @@ impl<'a> Parser<'a> {
1528
1528
pub fn parse_optional_cast_format ( & mut self ) -> Result < Option < CastFormat > , ParserError > {
1529
1529
if self . parse_keyword ( Keyword :: FORMAT ) {
1530
1530
let value = self . parse_value ( ) ?;
1531
- if self . parse_keywords ( & [ Keyword :: AT , Keyword :: TIME , Keyword :: ZONE ] ) {
1532
- Ok ( Some ( CastFormat :: ValueAtTimeZone (
1533
- value,
1534
- self . parse_value ( ) ?,
1535
- ) ) )
1536
- } else {
1537
- Ok ( Some ( CastFormat :: Value ( value) ) )
1531
+ match self . parse_optional_time_zone ( ) ? {
1532
+ Some ( tz) => Ok ( Some ( CastFormat :: ValueAtTimeZone ( value, tz) ) ) ,
1533
+ None => Ok ( Some ( CastFormat :: Value ( value) ) ) ,
1538
1534
}
1539
1535
} else {
1540
1536
Ok ( None )
1541
1537
}
1542
1538
}
1543
1539
1540
+ pub fn parse_optional_time_zone ( & mut self ) -> Result < Option < Value > , ParserError > {
1541
+ if self . parse_keywords ( & [ Keyword :: AT , Keyword :: TIME , Keyword :: ZONE ] ) {
1542
+ self . parse_value ( ) . map ( Some )
1543
+ } else {
1544
+ Ok ( None )
1545
+ }
1546
+ }
1547
+
1544
1548
/// mssql-like convert function
1545
1549
fn parse_mssql_convert ( & mut self ) -> Result < Expr , ParserError > {
1546
1550
self . expect_token ( & Token :: LParen ) ?;
@@ -2458,8 +2462,6 @@ impl<'a> Parser<'a> {
2458
2462
}
2459
2463
}
2460
2464
Keyword :: AT => {
2461
- // if self.parse_keyword(Keyword::TIME) {
2462
- // self.expect_keyword(Keyword::ZONE)?;
2463
2465
if self . parse_keywords ( & [ Keyword :: TIME , Keyword :: ZONE ] ) {
2464
2466
let time_zone = self . next_token ( ) ;
2465
2467
match time_zone. token {
@@ -2534,12 +2536,35 @@ impl<'a> Parser<'a> {
2534
2536
) ,
2535
2537
}
2536
2538
} else if Token :: DoubleColon == tok {
2537
- Ok ( Expr :: Cast {
2538
- kind : CastKind :: DoubleColon ,
2539
+ let data_type = self . parse_data_type ( ) ?;
2540
+
2541
+ let cast_expr = Expr :: Cast {
2542
+ kind : CastKind :: DoubleColonCast ,
2539
2543
expr : Box :: new ( expr) ,
2540
- data_type : self . parse_data_type ( ) ? ,
2544
+ data_type : data_type . clone ( ) ,
2541
2545
format : None ,
2542
- } )
2546
+ } ;
2547
+
2548
+ match data_type {
2549
+ DataType :: Date
2550
+ | DataType :: Datetime ( _)
2551
+ | DataType :: Timestamp ( _, _)
2552
+ | DataType :: Time ( _, _) => {
2553
+ let value = self . parse_optional_time_zone ( ) ?;
2554
+ match value {
2555
+ Some ( Value :: SingleQuotedString ( tz) ) => Ok ( Expr :: AtTimeZone {
2556
+ timestamp : Box :: new ( cast_expr) ,
2557
+ time_zone : tz,
2558
+ } ) ,
2559
+ None => Ok ( cast_expr) ,
2560
+ _ => Err ( ParserError :: ParserError ( format ! (
2561
+ "Expected Token::SingleQuotedString after AT TIME ZONE, but found: {}" ,
2562
+ value. unwrap( )
2563
+ ) ) ) ,
2564
+ }
2565
+ }
2566
+ _ => Ok ( cast_expr) ,
2567
+ }
2543
2568
} else if Token :: ExclamationMark == tok {
2544
2569
// PostgreSQL factorial operation
2545
2570
Ok ( Expr :: UnaryOp {
@@ -2738,16 +2763,6 @@ impl<'a> Parser<'a> {
2738
2763
} )
2739
2764
}
2740
2765
2741
- /// Parse a postgresql casting style which is in the form of `expr::datatype`
2742
- pub fn parse_pg_cast ( & mut self , expr : Expr ) -> Result < Expr , ParserError > {
2743
- Ok ( Expr :: Cast {
2744
- kind : CastKind :: DoubleColon ,
2745
- expr : Box :: new ( expr) ,
2746
- data_type : self . parse_data_type ( ) ?,
2747
- format : None ,
2748
- } )
2749
- }
2750
-
2751
2766
// use https://www.postgresql.org/docs/7.0/operators.htm#AEN2026 as a reference
2752
2767
// higher number = higher precedence
2753
2768
const MUL_DIV_MOD_OP_PREC : u8 = 40 ;
@@ -2967,7 +2982,7 @@ impl<'a> Parser<'a> {
2967
2982
token => {
2968
2983
return token
2969
2984
. cloned ( )
2970
- . unwrap_or_else ( || TokenWithLocation :: wrap ( Token :: EOF ) )
2985
+ . unwrap_or_else ( || TokenWithLocation :: wrap ( Token :: EOF ) ) ;
2971
2986
}
2972
2987
}
2973
2988
}
@@ -6968,12 +6983,12 @@ impl<'a> Parser<'a> {
6968
6983
Token :: EOF => {
6969
6984
return Err ( ParserError :: ParserError (
6970
6985
"Empty input when parsing identifier" . to_string ( ) ,
6971
- ) ) ?
6986
+ ) ) ?;
6972
6987
}
6973
6988
token => {
6974
6989
return Err ( ParserError :: ParserError ( format ! (
6975
6990
"Unexpected token in identifier: {token}"
6976
- ) ) ) ?
6991
+ ) ) ) ?;
6977
6992
}
6978
6993
} ;
6979
6994
@@ -6986,19 +7001,19 @@ impl<'a> Parser<'a> {
6986
7001
Token :: EOF => {
6987
7002
return Err ( ParserError :: ParserError (
6988
7003
"Trailing period in identifier" . to_string ( ) ,
6989
- ) ) ?
7004
+ ) ) ?;
6990
7005
}
6991
7006
token => {
6992
7007
return Err ( ParserError :: ParserError ( format ! (
6993
7008
"Unexpected token following period in identifier: {token}"
6994
- ) ) ) ?
7009
+ ) ) ) ?;
6995
7010
}
6996
7011
} ,
6997
7012
Token :: EOF => break ,
6998
7013
token => {
6999
7014
return Err ( ParserError :: ParserError ( format ! (
7000
7015
"Unexpected token in identifier: {token}"
7001
- ) ) ) ?
7016
+ ) ) ) ?;
7002
7017
}
7003
7018
}
7004
7019
}
@@ -8371,7 +8386,7 @@ impl<'a> Parser<'a> {
8371
8386
_ => {
8372
8387
return Err ( ParserError :: ParserError ( format ! (
8373
8388
"expected OUTER, SEMI, ANTI or JOIN after {kw:?}"
8374
- ) ) )
8389
+ ) ) ) ;
8375
8390
}
8376
8391
}
8377
8392
}
0 commit comments