@@ -44,8 +44,8 @@ pub enum ParserError {
44
44
45
45
// Use `Parser::expected` instead, if possible
46
46
macro_rules! parser_err {
47
- ( $MSG: expr) => {
48
- Err ( ParserError :: ParserError ( $MSG. to_string ( ) ) )
47
+ ( $MSG: expr, $loc : expr ) => {
48
+ Err ( ParserError :: ParserError ( format! ( "{}{}" , $MSG, $loc ) ) )
49
49
} ;
50
50
}
51
51
@@ -368,8 +368,8 @@ impl<'a> Parser<'a> {
368
368
debug ! ( "Parsing sql '{}'..." , sql) ;
369
369
let tokens = Tokenizer :: new ( self . dialect , sql)
370
370
. with_unescape ( self . options . unescape )
371
- . tokenize ( ) ?;
372
- Ok ( self . with_tokens ( tokens) )
371
+ . tokenize_with_location ( ) ?;
372
+ Ok ( self . with_tokens_with_locations ( tokens) )
373
373
}
374
374
375
375
/// Parse potentially multiple statements
@@ -724,6 +724,7 @@ impl<'a> Parser<'a> {
724
724
// Note also that naively `SELECT date` looks like a syntax error because the `date` type
725
725
// name is not followed by a string literal, but in fact in PostgreSQL it is a valid
726
726
// expression that should parse as the column name "date".
727
+ let loc = self . peek_token ( ) . location ;
727
728
return_ok_if_some ! ( self . maybe_parse( |parser| {
728
729
match parser. parse_data_type( ) ? {
729
730
DataType :: Interval => parser. parse_interval( ) ,
@@ -734,7 +735,7 @@ impl<'a> Parser<'a> {
734
735
// name, resulting in `NOT 'a'` being recognized as a `TypedString` instead of
735
736
// an unary negation `NOT ('a' LIKE 'b')`. To solve this, we don't accept the
736
737
// `type 'string'` syntax for the custom data types at all.
737
- DataType :: Custom ( ..) => parser_err!( "dummy" ) ,
738
+ DataType :: Custom ( ..) => parser_err!( "dummy" , loc ) ,
738
739
data_type => Ok ( Expr :: TypedString {
739
740
data_type,
740
741
value: parser. parse_literal_string( ) ?,
@@ -909,7 +910,12 @@ impl<'a> Parser<'a> {
909
910
let tok = self . next_token ( ) ;
910
911
let key = match tok. token {
911
912
Token :: Word ( word) => word. to_ident ( ) ,
912
- _ => return parser_err ! ( format!( "Expected identifier, found: {tok}" ) ) ,
913
+ _ => {
914
+ return parser_err ! (
915
+ format!( "Expected identifier, found: {tok}" ) ,
916
+ tok. location
917
+ )
918
+ }
913
919
} ;
914
920
Ok ( Expr :: CompositeAccess {
915
921
expr : Box :: new ( expr) ,
@@ -1220,7 +1226,10 @@ impl<'a> Parser<'a> {
1220
1226
r#in : Box :: new ( from) ,
1221
1227
} )
1222
1228
} else {
1223
- parser_err ! ( "Position function must include IN keyword" . to_string( ) )
1229
+ parser_err ! (
1230
+ "Position function must include IN keyword" . to_string( ) ,
1231
+ self . peek_token( ) . location
1232
+ )
1224
1233
}
1225
1234
}
1226
1235
@@ -1884,7 +1893,10 @@ impl<'a> Parser<'a> {
1884
1893
}
1885
1894
}
1886
1895
// Can only happen if `get_next_precedence` got out of sync with this function
1887
- _ => parser_err ! ( format!( "No infix parser for token {:?}" , tok. token) ) ,
1896
+ _ => parser_err ! (
1897
+ format!( "No infix parser for token {:?}" , tok. token) ,
1898
+ tok. location
1899
+ ) ,
1888
1900
}
1889
1901
} else if Token :: DoubleColon == tok {
1890
1902
self . parse_pg_cast ( expr)
@@ -1935,7 +1947,10 @@ impl<'a> Parser<'a> {
1935
1947
} )
1936
1948
} else {
1937
1949
// Can only happen if `get_next_precedence` got out of sync with this function
1938
- parser_err ! ( format!( "No infix parser for token {:?}" , tok. token) )
1950
+ parser_err ! (
1951
+ format!( "No infix parser for token {:?}" , tok. token) ,
1952
+ tok. location
1953
+ )
1939
1954
}
1940
1955
}
1941
1956
@@ -2213,7 +2228,10 @@ impl<'a> Parser<'a> {
2213
2228
2214
2229
/// Report unexpected token
2215
2230
pub fn expected < T > ( & self , expected : & str , found : TokenWithLocation ) -> Result < T , ParserError > {
2216
- parser_err ! ( format!( "Expected {expected}, found: {found}" ) )
2231
+ parser_err ! (
2232
+ format!( "Expected {expected}, found: {found}" ) ,
2233
+ found. location
2234
+ )
2217
2235
}
2218
2236
2219
2237
/// Look for an expected keyword and consume it if it exists
@@ -2378,13 +2396,14 @@ impl<'a> Parser<'a> {
2378
2396
/// Parse either `ALL`, `DISTINCT` or `DISTINCT ON (...)`. Returns `None` if `ALL` is parsed
2379
2397
/// and results in a `ParserError` if both `ALL` and `DISTINCT` are found.
2380
2398
pub fn parse_all_or_distinct ( & mut self ) -> Result < Option < Distinct > , ParserError > {
2399
+ let loc = self . peek_token ( ) . location ;
2381
2400
let all = self . parse_keyword ( Keyword :: ALL ) ;
2382
2401
let distinct = self . parse_keyword ( Keyword :: DISTINCT ) ;
2383
2402
if !distinct {
2384
2403
return Ok ( None ) ;
2385
2404
}
2386
2405
if all {
2387
- return parser_err ! ( "Cannot specify both ALL and DISTINCT" . to_string( ) ) ;
2406
+ return parser_err ! ( "Cannot specify both ALL and DISTINCT" . to_string( ) , loc ) ;
2388
2407
}
2389
2408
let on = self . parse_keyword ( Keyword :: ON ) ;
2390
2409
if !on {
@@ -2986,74 +3005,78 @@ impl<'a> Parser<'a> {
2986
3005
let mut admin = vec ! [ ] ;
2987
3006
2988
3007
while let Some ( keyword) = self . parse_one_of_keywords ( & optional_keywords) {
3008
+ let loc = self
3009
+ . tokens
3010
+ . get ( self . index - 1 )
3011
+ . map_or ( Location { line : 0 , column : 0 } , |t| t. location ) ;
2989
3012
match keyword {
2990
3013
Keyword :: AUTHORIZATION => {
2991
3014
if authorization_owner. is_some ( ) {
2992
- parser_err ! ( "Found multiple AUTHORIZATION" )
3015
+ parser_err ! ( "Found multiple AUTHORIZATION" , loc )
2993
3016
} else {
2994
3017
authorization_owner = Some ( self . parse_object_name ( ) ?) ;
2995
3018
Ok ( ( ) )
2996
3019
}
2997
3020
}
2998
3021
Keyword :: LOGIN | Keyword :: NOLOGIN => {
2999
3022
if login. is_some ( ) {
3000
- parser_err ! ( "Found multiple LOGIN or NOLOGIN" )
3023
+ parser_err ! ( "Found multiple LOGIN or NOLOGIN" , loc )
3001
3024
} else {
3002
3025
login = Some ( keyword == Keyword :: LOGIN ) ;
3003
3026
Ok ( ( ) )
3004
3027
}
3005
3028
}
3006
3029
Keyword :: INHERIT | Keyword :: NOINHERIT => {
3007
3030
if inherit. is_some ( ) {
3008
- parser_err ! ( "Found multiple INHERIT or NOINHERIT" )
3031
+ parser_err ! ( "Found multiple INHERIT or NOINHERIT" , loc )
3009
3032
} else {
3010
3033
inherit = Some ( keyword == Keyword :: INHERIT ) ;
3011
3034
Ok ( ( ) )
3012
3035
}
3013
3036
}
3014
3037
Keyword :: BYPASSRLS | Keyword :: NOBYPASSRLS => {
3015
3038
if bypassrls. is_some ( ) {
3016
- parser_err ! ( "Found multiple BYPASSRLS or NOBYPASSRLS" )
3039
+ parser_err ! ( "Found multiple BYPASSRLS or NOBYPASSRLS" , loc )
3017
3040
} else {
3018
3041
bypassrls = Some ( keyword == Keyword :: BYPASSRLS ) ;
3019
3042
Ok ( ( ) )
3020
3043
}
3021
3044
}
3022
3045
Keyword :: CREATEDB | Keyword :: NOCREATEDB => {
3023
3046
if create_db. is_some ( ) {
3024
- parser_err ! ( "Found multiple CREATEDB or NOCREATEDB" )
3047
+ parser_err ! ( "Found multiple CREATEDB or NOCREATEDB" , loc )
3025
3048
} else {
3026
3049
create_db = Some ( keyword == Keyword :: CREATEDB ) ;
3027
3050
Ok ( ( ) )
3028
3051
}
3029
3052
}
3030
3053
Keyword :: CREATEROLE | Keyword :: NOCREATEROLE => {
3031
3054
if create_role. is_some ( ) {
3032
- parser_err ! ( "Found multiple CREATEROLE or NOCREATEROLE" )
3055
+ parser_err ! ( "Found multiple CREATEROLE or NOCREATEROLE" , loc )
3033
3056
} else {
3034
3057
create_role = Some ( keyword == Keyword :: CREATEROLE ) ;
3035
3058
Ok ( ( ) )
3036
3059
}
3037
3060
}
3038
3061
Keyword :: SUPERUSER | Keyword :: NOSUPERUSER => {
3039
3062
if superuser. is_some ( ) {
3040
- parser_err ! ( "Found multiple SUPERUSER or NOSUPERUSER" )
3063
+ parser_err ! ( "Found multiple SUPERUSER or NOSUPERUSER" , loc )
3041
3064
} else {
3042
3065
superuser = Some ( keyword == Keyword :: SUPERUSER ) ;
3043
3066
Ok ( ( ) )
3044
3067
}
3045
3068
}
3046
3069
Keyword :: REPLICATION | Keyword :: NOREPLICATION => {
3047
3070
if replication. is_some ( ) {
3048
- parser_err ! ( "Found multiple REPLICATION or NOREPLICATION" )
3071
+ parser_err ! ( "Found multiple REPLICATION or NOREPLICATION" , loc )
3049
3072
} else {
3050
3073
replication = Some ( keyword == Keyword :: REPLICATION ) ;
3051
3074
Ok ( ( ) )
3052
3075
}
3053
3076
}
3054
3077
Keyword :: PASSWORD => {
3055
3078
if password. is_some ( ) {
3056
- parser_err ! ( "Found multiple PASSWORD" )
3079
+ parser_err ! ( "Found multiple PASSWORD" , loc )
3057
3080
} else {
3058
3081
password = if self . parse_keyword ( Keyword :: NULL ) {
3059
3082
Some ( Password :: NullPassword )
@@ -3066,7 +3089,7 @@ impl<'a> Parser<'a> {
3066
3089
Keyword :: CONNECTION => {
3067
3090
self . expect_keyword ( Keyword :: LIMIT ) ?;
3068
3091
if connection_limit. is_some ( ) {
3069
- parser_err ! ( "Found multiple CONNECTION LIMIT" )
3092
+ parser_err ! ( "Found multiple CONNECTION LIMIT" , loc )
3070
3093
} else {
3071
3094
connection_limit = Some ( Expr :: Value ( self . parse_number_value ( ) ?) ) ;
3072
3095
Ok ( ( ) )
@@ -3075,7 +3098,7 @@ impl<'a> Parser<'a> {
3075
3098
Keyword :: VALID => {
3076
3099
self . expect_keyword ( Keyword :: UNTIL ) ?;
3077
3100
if valid_until. is_some ( ) {
3078
- parser_err ! ( "Found multiple VALID UNTIL" )
3101
+ parser_err ! ( "Found multiple VALID UNTIL" , loc )
3079
3102
} else {
3080
3103
valid_until = Some ( Expr :: Value ( self . parse_value ( ) ?) ) ;
3081
3104
Ok ( ( ) )
@@ -3084,14 +3107,14 @@ impl<'a> Parser<'a> {
3084
3107
Keyword :: IN => {
3085
3108
if self . parse_keyword ( Keyword :: ROLE ) {
3086
3109
if !in_role. is_empty ( ) {
3087
- parser_err ! ( "Found multiple IN ROLE" )
3110
+ parser_err ! ( "Found multiple IN ROLE" , loc )
3088
3111
} else {
3089
3112
in_role = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3090
3113
Ok ( ( ) )
3091
3114
}
3092
3115
} else if self . parse_keyword ( Keyword :: GROUP ) {
3093
3116
if !in_group. is_empty ( ) {
3094
- parser_err ! ( "Found multiple IN GROUP" )
3117
+ parser_err ! ( "Found multiple IN GROUP" , loc )
3095
3118
} else {
3096
3119
in_group = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3097
3120
Ok ( ( ) )
@@ -3102,23 +3125,23 @@ impl<'a> Parser<'a> {
3102
3125
}
3103
3126
Keyword :: ROLE => {
3104
3127
if !role. is_empty ( ) {
3105
- parser_err ! ( "Found multiple ROLE" )
3128
+ parser_err ! ( "Found multiple ROLE" , loc )
3106
3129
} else {
3107
3130
role = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3108
3131
Ok ( ( ) )
3109
3132
}
3110
3133
}
3111
3134
Keyword :: USER => {
3112
3135
if !user. is_empty ( ) {
3113
- parser_err ! ( "Found multiple USER" )
3136
+ parser_err ! ( "Found multiple USER" , loc )
3114
3137
} else {
3115
3138
user = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3116
3139
Ok ( ( ) )
3117
3140
}
3118
3141
}
3119
3142
Keyword :: ADMIN => {
3120
3143
if !admin. is_empty ( ) {
3121
- parser_err ! ( "Found multiple ADMIN" )
3144
+ parser_err ! ( "Found multiple ADMIN" , loc )
3122
3145
} else {
3123
3146
admin = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3124
3147
Ok ( ( ) )
@@ -3181,14 +3204,19 @@ impl<'a> Parser<'a> {
3181
3204
// specifying multiple objects to delete in a single statement
3182
3205
let if_exists = self . parse_keywords ( & [ Keyword :: IF , Keyword :: EXISTS ] ) ;
3183
3206
let names = self . parse_comma_separated ( Parser :: parse_object_name) ?;
3207
+
3208
+ let loc = self . peek_token ( ) . location ;
3184
3209
let cascade = self . parse_keyword ( Keyword :: CASCADE ) ;
3185
3210
let restrict = self . parse_keyword ( Keyword :: RESTRICT ) ;
3186
3211
let purge = self . parse_keyword ( Keyword :: PURGE ) ;
3187
3212
if cascade && restrict {
3188
- return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in DROP" ) ;
3213
+ return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in DROP" , loc ) ;
3189
3214
}
3190
3215
if object_type == ObjectType :: Role && ( cascade || restrict || purge) {
3191
- return parser_err ! ( "Cannot specify CASCADE, RESTRICT, or PURGE in DROP ROLE" ) ;
3216
+ return parser_err ! (
3217
+ "Cannot specify CASCADE, RESTRICT, or PURGE in DROP ROLE" ,
3218
+ loc
3219
+ ) ;
3192
3220
}
3193
3221
Ok ( Statement :: Drop {
3194
3222
object_type,
@@ -4446,7 +4474,11 @@ impl<'a> Parser<'a> {
4446
4474
fn parse_literal_char ( & mut self ) -> Result < char , ParserError > {
4447
4475
let s = self . parse_literal_string ( ) ?;
4448
4476
if s. len ( ) != 1 {
4449
- return parser_err ! ( format!( "Expect a char, found {s:?}" ) ) ;
4477
+ let loc = self
4478
+ . tokens
4479
+ . get ( self . index - 1 )
4480
+ . map_or ( Location { line : 0 , column : 0 } , |t| t. location ) ;
4481
+ return parser_err ! ( format!( "Expect a char, found {s:?}" ) , loc) ;
4450
4482
}
4451
4483
Ok ( s. chars ( ) . next ( ) . unwrap ( ) )
4452
4484
}
@@ -4525,7 +4557,7 @@ impl<'a> Parser<'a> {
4525
4557
// (i.e., it returns the input string).
4526
4558
Token :: Number ( ref n, l) => match n. parse ( ) {
4527
4559
Ok ( n) => Ok ( Value :: Number ( n, l) ) ,
4528
- Err ( e) => parser_err ! ( format!( "Could not parse '{n}' as number: {e}" ) ) ,
4560
+ Err ( e) => parser_err ! ( format!( "Could not parse '{n}' as number: {e}" ) , location ) ,
4529
4561
} ,
4530
4562
Token :: SingleQuotedString ( ref s) => Ok ( Value :: SingleQuotedString ( s. to_string ( ) ) ) ,
4531
4563
Token :: DoubleQuotedString ( ref s) => Ok ( Value :: DoubleQuotedString ( s. to_string ( ) ) ) ,
@@ -6465,10 +6497,11 @@ impl<'a> Parser<'a> {
6465
6497
. parse_keywords ( & [ Keyword :: GRANTED , Keyword :: BY ] )
6466
6498
. then ( || self . parse_identifier ( ) . unwrap ( ) ) ;
6467
6499
6500
+ let loc = self . peek_token ( ) . location ;
6468
6501
let cascade = self . parse_keyword ( Keyword :: CASCADE ) ;
6469
6502
let restrict = self . parse_keyword ( Keyword :: RESTRICT ) ;
6470
6503
if cascade && restrict {
6471
- return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in REVOKE" ) ;
6504
+ return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in REVOKE" , loc ) ;
6472
6505
}
6473
6506
6474
6507
Ok ( Statement :: Revoke {
@@ -7929,14 +7962,12 @@ mod tests {
7929
7962
7930
7963
#[ test]
7931
7964
fn test_parser_error_loc ( ) {
7932
- // TODO: Once we thread token locations through the parser, we should update this
7933
- // test to assert the locations of the referenced token
7934
7965
let sql = "SELECT this is a syntax error" ;
7935
7966
let ast = Parser :: parse_sql ( & GenericDialect , sql) ;
7936
7967
assert_eq ! (
7937
7968
ast,
7938
7969
Err ( ParserError :: ParserError (
7939
- "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a"
7970
+ "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a at Line: 1, Column 16 "
7940
7971
. to_string( )
7941
7972
) )
7942
7973
) ;
0 commit comments