@@ -56,15 +56,6 @@ macro_rules! parser_err {
56
56
} ;
57
57
}
58
58
59
- // Returns a successful result if the optional expression is some
60
- macro_rules! return_ok_if_some {
61
- ( $e: expr) => { {
62
- if let Some ( v) = $e {
63
- return Ok ( v) ;
64
- }
65
- } } ;
66
- }
67
-
68
59
#[ cfg( feature = "std" ) ]
69
60
/// Implementation [`RecursionCounter`] if std is available
70
61
mod recursion {
@@ -928,35 +919,6 @@ impl<'a> Parser<'a> {
928
919
Ok ( expr)
929
920
}
930
921
931
- pub fn parse_interval_expr ( & mut self ) -> Result < Expr , ParserError > {
932
- let precedence = self . dialect . prec_unknown ( ) ;
933
- let mut expr = self . parse_prefix ( ) ?;
934
-
935
- loop {
936
- let next_precedence = self . get_next_interval_precedence ( ) ?;
937
-
938
- if precedence >= next_precedence {
939
- break ;
940
- }
941
-
942
- expr = self . parse_infix ( expr, next_precedence) ?;
943
- }
944
-
945
- Ok ( expr)
946
- }
947
-
948
- /// Get the precedence of the next token, with AND, OR, and XOR.
949
- pub fn get_next_interval_precedence ( & self ) -> Result < u8 , ParserError > {
950
- let token = self . peek_token ( ) ;
951
-
952
- match token. token {
953
- Token :: Word ( w) if w. keyword == Keyword :: AND => Ok ( self . dialect . prec_unknown ( ) ) ,
954
- Token :: Word ( w) if w. keyword == Keyword :: OR => Ok ( self . dialect . prec_unknown ( ) ) ,
955
- Token :: Word ( w) if w. keyword == Keyword :: XOR => Ok ( self . dialect . prec_unknown ( ) ) ,
956
- _ => self . get_next_precedence ( ) ,
957
- }
958
- }
959
-
960
922
pub fn parse_assert ( & mut self ) -> Result < Statement , ParserError > {
961
923
let condition = self . parse_expr ( ) ?;
962
924
let message = if self . parse_keyword ( Keyword :: AS ) {
@@ -1004,7 +966,7 @@ impl<'a> Parser<'a> {
1004
966
// name is not followed by a string literal, but in fact in PostgreSQL it is a valid
1005
967
// expression that should parse as the column name "date".
1006
968
let loc = self . peek_token ( ) . location ;
1007
- return_ok_if_some ! ( self . maybe_parse( |parser| {
969
+ let opt_expr = self . maybe_parse ( |parser| {
1008
970
match parser. parse_data_type ( ) ? {
1009
971
DataType :: Interval => parser. parse_interval ( ) ,
1010
972
// PostgreSQL allows almost any identifier to be used as custom data type name,
@@ -1020,7 +982,11 @@ impl<'a> Parser<'a> {
1020
982
value : parser. parse_literal_string ( ) ?,
1021
983
} ) ,
1022
984
}
1023
- } ) ) ;
985
+ } ) ;
986
+
987
+ if let Some ( expr) = opt_expr {
988
+ return Ok ( expr) ;
989
+ }
1024
990
1025
991
let next_token = self . next_token ( ) ;
1026
992
let expr = match next_token. token {
@@ -2110,52 +2076,32 @@ impl<'a> Parser<'a> {
2110
2076
// don't currently try to parse it. (The sign can instead be included
2111
2077
// inside the value string.)
2112
2078
2113
- // The first token in an interval is a string literal which specifies
2114
- // the duration of the interval.
2115
- let value = self . parse_interval_expr ( ) ?;
2079
+ // to match the different flavours of INTERVAL syntax, we only allow expressions
2080
+ // if the dialect requires an interval qualifier,
2081
+ // see https://github.com/sqlparser-rs/sqlparser-rs/pull/1398 for more details
2082
+ let value = if self . dialect . require_interval_qualifier ( ) {
2083
+ // parse a whole expression so `INTERVAL 1 + 1 DAY` is valid
2084
+ self . parse_expr ( ) ?
2085
+ } else {
2086
+ // parse a prefix expression so `INTERVAL 1 DAY` is valid, but `INTERVAL 1 + 1 DAY` is not
2087
+ // this also means that `INTERVAL '5 days' > INTERVAL '1 day'` treated properly
2088
+ self . parse_prefix ( ) ?
2089
+ } ;
2116
2090
2117
2091
// Following the string literal is a qualifier which indicates the units
2118
2092
// of the duration specified in the string literal.
2119
2093
//
2120
2094
// Note that PostgreSQL allows omitting the qualifier, so we provide
2121
2095
// this more general implementation.
2122
- let leading_field = match self . peek_token ( ) . token {
2123
- Token :: Word ( kw)
2124
- if [
2125
- Keyword :: YEAR ,
2126
- Keyword :: MONTH ,
2127
- Keyword :: WEEK ,
2128
- Keyword :: DAY ,
2129
- Keyword :: HOUR ,
2130
- Keyword :: MINUTE ,
2131
- Keyword :: SECOND ,
2132
- Keyword :: CENTURY ,
2133
- Keyword :: DECADE ,
2134
- Keyword :: DOW ,
2135
- Keyword :: DOY ,
2136
- Keyword :: EPOCH ,
2137
- Keyword :: ISODOW ,
2138
- Keyword :: ISOYEAR ,
2139
- Keyword :: JULIAN ,
2140
- Keyword :: MICROSECOND ,
2141
- Keyword :: MICROSECONDS ,
2142
- Keyword :: MILLENIUM ,
2143
- Keyword :: MILLENNIUM ,
2144
- Keyword :: MILLISECOND ,
2145
- Keyword :: MILLISECONDS ,
2146
- Keyword :: NANOSECOND ,
2147
- Keyword :: NANOSECONDS ,
2148
- Keyword :: QUARTER ,
2149
- Keyword :: TIMEZONE ,
2150
- Keyword :: TIMEZONE_HOUR ,
2151
- Keyword :: TIMEZONE_MINUTE ,
2152
- ]
2153
- . iter ( )
2154
- . any ( |d| kw. keyword == * d) =>
2155
- {
2156
- Some ( self . parse_date_time_field ( ) ?)
2157
- }
2158
- _ => None ,
2096
+ let leading_field = if self . next_token_is_temporal_unit ( ) {
2097
+ Some ( self . parse_date_time_field ( ) ?)
2098
+ } else if self . dialect . require_interval_qualifier ( ) {
2099
+ return parser_err ! (
2100
+ "INTERVAL requires a unit after the literal value" ,
2101
+ self . peek_token( ) . location
2102
+ ) ;
2103
+ } else {
2104
+ None
2159
2105
} ;
2160
2106
2161
2107
let ( leading_precision, last_field, fsec_precision) =
@@ -2192,6 +2138,45 @@ impl<'a> Parser<'a> {
2192
2138
} ) )
2193
2139
}
2194
2140
2141
+ /// Peek at the next token and determine if it is a temporal unit
2142
+ /// like `second`.
2143
+ pub fn next_token_is_temporal_unit ( & mut self ) -> bool {
2144
+ if let Token :: Word ( word) = self . peek_token ( ) . token {
2145
+ matches ! (
2146
+ word. keyword,
2147
+ Keyword :: YEAR
2148
+ | Keyword :: MONTH
2149
+ | Keyword :: WEEK
2150
+ | Keyword :: DAY
2151
+ | Keyword :: HOUR
2152
+ | Keyword :: MINUTE
2153
+ | Keyword :: SECOND
2154
+ | Keyword :: CENTURY
2155
+ | Keyword :: DECADE
2156
+ | Keyword :: DOW
2157
+ | Keyword :: DOY
2158
+ | Keyword :: EPOCH
2159
+ | Keyword :: ISODOW
2160
+ | Keyword :: ISOYEAR
2161
+ | Keyword :: JULIAN
2162
+ | Keyword :: MICROSECOND
2163
+ | Keyword :: MICROSECONDS
2164
+ | Keyword :: MILLENIUM
2165
+ | Keyword :: MILLENNIUM
2166
+ | Keyword :: MILLISECOND
2167
+ | Keyword :: MILLISECONDS
2168
+ | Keyword :: NANOSECOND
2169
+ | Keyword :: NANOSECONDS
2170
+ | Keyword :: QUARTER
2171
+ | Keyword :: TIMEZONE
2172
+ | Keyword :: TIMEZONE_HOUR
2173
+ | Keyword :: TIMEZONE_MINUTE
2174
+ )
2175
+ } else {
2176
+ false
2177
+ }
2178
+ }
2179
+
2195
2180
/// Bigquery specific: Parse a struct literal
2196
2181
/// Syntax
2197
2182
/// ```sql
0 commit comments