@@ -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
@@ -728,6 +728,7 @@ impl<'a> Parser<'a> {
728
728
// Note also that naively `SELECT date` looks like a syntax error because the `date` type
729
729
// name is not followed by a string literal, but in fact in PostgreSQL it is a valid
730
730
// expression that should parse as the column name "date".
731
+ let loc = self . peek_token ( ) . location ;
731
732
return_ok_if_some ! ( self . maybe_parse( |parser| {
732
733
match parser. parse_data_type( ) ? {
733
734
DataType :: Interval => parser. parse_interval( ) ,
@@ -738,7 +739,7 @@ impl<'a> Parser<'a> {
738
739
// name, resulting in `NOT 'a'` being recognized as a `TypedString` instead of
739
740
// an unary negation `NOT ('a' LIKE 'b')`. To solve this, we don't accept the
740
741
// `type 'string'` syntax for the custom data types at all.
741
- DataType :: Custom ( ..) => parser_err!( "dummy" ) ,
742
+ DataType :: Custom ( ..) => parser_err!( "dummy" , loc ) ,
742
743
data_type => Ok ( Expr :: TypedString {
743
744
data_type,
744
745
value: parser. parse_literal_string( ) ?,
@@ -913,7 +914,12 @@ impl<'a> Parser<'a> {
913
914
let tok = self . next_token ( ) ;
914
915
let key = match tok. token {
915
916
Token :: Word ( word) => word. to_ident ( ) ,
916
- _ => return parser_err ! ( format!( "Expected identifier, found: {tok}" ) ) ,
917
+ _ => {
918
+ return parser_err ! (
919
+ format!( "Expected identifier, found: {tok}" ) ,
920
+ tok. location
921
+ )
922
+ }
917
923
} ;
918
924
Ok ( Expr :: CompositeAccess {
919
925
expr : Box :: new ( expr) ,
@@ -1224,7 +1230,10 @@ impl<'a> Parser<'a> {
1224
1230
r#in : Box :: new ( from) ,
1225
1231
} )
1226
1232
} else {
1227
- parser_err ! ( "Position function must include IN keyword" . to_string( ) )
1233
+ parser_err ! (
1234
+ "Position function must include IN keyword" . to_string( ) ,
1235
+ self . peek_token( ) . location
1236
+ )
1228
1237
}
1229
1238
}
1230
1239
@@ -1888,7 +1897,10 @@ impl<'a> Parser<'a> {
1888
1897
}
1889
1898
}
1890
1899
// Can only happen if `get_next_precedence` got out of sync with this function
1891
- _ => parser_err ! ( format!( "No infix parser for token {:?}" , tok. token) ) ,
1900
+ _ => parser_err ! (
1901
+ format!( "No infix parser for token {:?}" , tok. token) ,
1902
+ tok. location
1903
+ ) ,
1892
1904
}
1893
1905
} else if Token :: DoubleColon == tok {
1894
1906
self . parse_pg_cast ( expr)
@@ -1939,7 +1951,10 @@ impl<'a> Parser<'a> {
1939
1951
} )
1940
1952
} else {
1941
1953
// Can only happen if `get_next_precedence` got out of sync with this function
1942
- parser_err ! ( format!( "No infix parser for token {:?}" , tok. token) )
1954
+ parser_err ! (
1955
+ format!( "No infix parser for token {:?}" , tok. token) ,
1956
+ tok. location
1957
+ )
1943
1958
}
1944
1959
}
1945
1960
@@ -2217,7 +2232,10 @@ impl<'a> Parser<'a> {
2217
2232
2218
2233
/// Report unexpected token
2219
2234
pub fn expected < T > ( & self , expected : & str , found : TokenWithLocation ) -> Result < T , ParserError > {
2220
- parser_err ! ( format!( "Expected {expected}, found: {found}" ) )
2235
+ parser_err ! (
2236
+ format!( "Expected {expected}, found: {found}" ) ,
2237
+ found. location
2238
+ )
2221
2239
}
2222
2240
2223
2241
/// Look for an expected keyword and consume it if it exists
@@ -2382,13 +2400,14 @@ impl<'a> Parser<'a> {
2382
2400
/// Parse either `ALL`, `DISTINCT` or `DISTINCT ON (...)`. Returns `None` if `ALL` is parsed
2383
2401
/// and results in a `ParserError` if both `ALL` and `DISTINCT` are found.
2384
2402
pub fn parse_all_or_distinct ( & mut self ) -> Result < Option < Distinct > , ParserError > {
2403
+ let loc = self . peek_token ( ) . location ;
2385
2404
let all = self . parse_keyword ( Keyword :: ALL ) ;
2386
2405
let distinct = self . parse_keyword ( Keyword :: DISTINCT ) ;
2387
2406
if !distinct {
2388
2407
return Ok ( None ) ;
2389
2408
}
2390
2409
if all {
2391
- return parser_err ! ( "Cannot specify both ALL and DISTINCT" . to_string( ) ) ;
2410
+ return parser_err ! ( "Cannot specify both ALL and DISTINCT" . to_string( ) , loc ) ;
2392
2411
}
2393
2412
let on = self . parse_keyword ( Keyword :: ON ) ;
2394
2413
if !on {
@@ -2994,74 +3013,78 @@ impl<'a> Parser<'a> {
2994
3013
let mut admin = vec ! [ ] ;
2995
3014
2996
3015
while let Some ( keyword) = self . parse_one_of_keywords ( & optional_keywords) {
3016
+ let loc = self
3017
+ . tokens
3018
+ . get ( self . index - 1 )
3019
+ . map_or ( Location { line : 0 , column : 0 } , |t| t. location ) ;
2997
3020
match keyword {
2998
3021
Keyword :: AUTHORIZATION => {
2999
3022
if authorization_owner. is_some ( ) {
3000
- parser_err ! ( "Found multiple AUTHORIZATION" )
3023
+ parser_err ! ( "Found multiple AUTHORIZATION" , loc )
3001
3024
} else {
3002
3025
authorization_owner = Some ( self . parse_object_name ( ) ?) ;
3003
3026
Ok ( ( ) )
3004
3027
}
3005
3028
}
3006
3029
Keyword :: LOGIN | Keyword :: NOLOGIN => {
3007
3030
if login. is_some ( ) {
3008
- parser_err ! ( "Found multiple LOGIN or NOLOGIN" )
3031
+ parser_err ! ( "Found multiple LOGIN or NOLOGIN" , loc )
3009
3032
} else {
3010
3033
login = Some ( keyword == Keyword :: LOGIN ) ;
3011
3034
Ok ( ( ) )
3012
3035
}
3013
3036
}
3014
3037
Keyword :: INHERIT | Keyword :: NOINHERIT => {
3015
3038
if inherit. is_some ( ) {
3016
- parser_err ! ( "Found multiple INHERIT or NOINHERIT" )
3039
+ parser_err ! ( "Found multiple INHERIT or NOINHERIT" , loc )
3017
3040
} else {
3018
3041
inherit = Some ( keyword == Keyword :: INHERIT ) ;
3019
3042
Ok ( ( ) )
3020
3043
}
3021
3044
}
3022
3045
Keyword :: BYPASSRLS | Keyword :: NOBYPASSRLS => {
3023
3046
if bypassrls. is_some ( ) {
3024
- parser_err ! ( "Found multiple BYPASSRLS or NOBYPASSRLS" )
3047
+ parser_err ! ( "Found multiple BYPASSRLS or NOBYPASSRLS" , loc )
3025
3048
} else {
3026
3049
bypassrls = Some ( keyword == Keyword :: BYPASSRLS ) ;
3027
3050
Ok ( ( ) )
3028
3051
}
3029
3052
}
3030
3053
Keyword :: CREATEDB | Keyword :: NOCREATEDB => {
3031
3054
if create_db. is_some ( ) {
3032
- parser_err ! ( "Found multiple CREATEDB or NOCREATEDB" )
3055
+ parser_err ! ( "Found multiple CREATEDB or NOCREATEDB" , loc )
3033
3056
} else {
3034
3057
create_db = Some ( keyword == Keyword :: CREATEDB ) ;
3035
3058
Ok ( ( ) )
3036
3059
}
3037
3060
}
3038
3061
Keyword :: CREATEROLE | Keyword :: NOCREATEROLE => {
3039
3062
if create_role. is_some ( ) {
3040
- parser_err ! ( "Found multiple CREATEROLE or NOCREATEROLE" )
3063
+ parser_err ! ( "Found multiple CREATEROLE or NOCREATEROLE" , loc )
3041
3064
} else {
3042
3065
create_role = Some ( keyword == Keyword :: CREATEROLE ) ;
3043
3066
Ok ( ( ) )
3044
3067
}
3045
3068
}
3046
3069
Keyword :: SUPERUSER | Keyword :: NOSUPERUSER => {
3047
3070
if superuser. is_some ( ) {
3048
- parser_err ! ( "Found multiple SUPERUSER or NOSUPERUSER" )
3071
+ parser_err ! ( "Found multiple SUPERUSER or NOSUPERUSER" , loc )
3049
3072
} else {
3050
3073
superuser = Some ( keyword == Keyword :: SUPERUSER ) ;
3051
3074
Ok ( ( ) )
3052
3075
}
3053
3076
}
3054
3077
Keyword :: REPLICATION | Keyword :: NOREPLICATION => {
3055
3078
if replication. is_some ( ) {
3056
- parser_err ! ( "Found multiple REPLICATION or NOREPLICATION" )
3079
+ parser_err ! ( "Found multiple REPLICATION or NOREPLICATION" , loc )
3057
3080
} else {
3058
3081
replication = Some ( keyword == Keyword :: REPLICATION ) ;
3059
3082
Ok ( ( ) )
3060
3083
}
3061
3084
}
3062
3085
Keyword :: PASSWORD => {
3063
3086
if password. is_some ( ) {
3064
- parser_err ! ( "Found multiple PASSWORD" )
3087
+ parser_err ! ( "Found multiple PASSWORD" , loc )
3065
3088
} else {
3066
3089
password = if self . parse_keyword ( Keyword :: NULL ) {
3067
3090
Some ( Password :: NullPassword )
@@ -3074,7 +3097,7 @@ impl<'a> Parser<'a> {
3074
3097
Keyword :: CONNECTION => {
3075
3098
self . expect_keyword ( Keyword :: LIMIT ) ?;
3076
3099
if connection_limit. is_some ( ) {
3077
- parser_err ! ( "Found multiple CONNECTION LIMIT" )
3100
+ parser_err ! ( "Found multiple CONNECTION LIMIT" , loc )
3078
3101
} else {
3079
3102
connection_limit = Some ( Expr :: Value ( self . parse_number_value ( ) ?) ) ;
3080
3103
Ok ( ( ) )
@@ -3083,7 +3106,7 @@ impl<'a> Parser<'a> {
3083
3106
Keyword :: VALID => {
3084
3107
self . expect_keyword ( Keyword :: UNTIL ) ?;
3085
3108
if valid_until. is_some ( ) {
3086
- parser_err ! ( "Found multiple VALID UNTIL" )
3109
+ parser_err ! ( "Found multiple VALID UNTIL" , loc )
3087
3110
} else {
3088
3111
valid_until = Some ( Expr :: Value ( self . parse_value ( ) ?) ) ;
3089
3112
Ok ( ( ) )
@@ -3092,14 +3115,14 @@ impl<'a> Parser<'a> {
3092
3115
Keyword :: IN => {
3093
3116
if self . parse_keyword ( Keyword :: ROLE ) {
3094
3117
if !in_role. is_empty ( ) {
3095
- parser_err ! ( "Found multiple IN ROLE" )
3118
+ parser_err ! ( "Found multiple IN ROLE" , loc )
3096
3119
} else {
3097
3120
in_role = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3098
3121
Ok ( ( ) )
3099
3122
}
3100
3123
} else if self . parse_keyword ( Keyword :: GROUP ) {
3101
3124
if !in_group. is_empty ( ) {
3102
- parser_err ! ( "Found multiple IN GROUP" )
3125
+ parser_err ! ( "Found multiple IN GROUP" , loc )
3103
3126
} else {
3104
3127
in_group = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3105
3128
Ok ( ( ) )
@@ -3110,23 +3133,23 @@ impl<'a> Parser<'a> {
3110
3133
}
3111
3134
Keyword :: ROLE => {
3112
3135
if !role. is_empty ( ) {
3113
- parser_err ! ( "Found multiple ROLE" )
3136
+ parser_err ! ( "Found multiple ROLE" , loc )
3114
3137
} else {
3115
3138
role = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3116
3139
Ok ( ( ) )
3117
3140
}
3118
3141
}
3119
3142
Keyword :: USER => {
3120
3143
if !user. is_empty ( ) {
3121
- parser_err ! ( "Found multiple USER" )
3144
+ parser_err ! ( "Found multiple USER" , loc )
3122
3145
} else {
3123
3146
user = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3124
3147
Ok ( ( ) )
3125
3148
}
3126
3149
}
3127
3150
Keyword :: ADMIN => {
3128
3151
if !admin. is_empty ( ) {
3129
- parser_err ! ( "Found multiple ADMIN" )
3152
+ parser_err ! ( "Found multiple ADMIN" , loc )
3130
3153
} else {
3131
3154
admin = self . parse_comma_separated ( Parser :: parse_identifier) ?;
3132
3155
Ok ( ( ) )
@@ -3193,14 +3216,19 @@ impl<'a> Parser<'a> {
3193
3216
// specifying multiple objects to delete in a single statement
3194
3217
let if_exists = self . parse_keywords ( & [ Keyword :: IF , Keyword :: EXISTS ] ) ;
3195
3218
let names = self . parse_comma_separated ( Parser :: parse_object_name) ?;
3219
+
3220
+ let loc = self . peek_token ( ) . location ;
3196
3221
let cascade = self . parse_keyword ( Keyword :: CASCADE ) ;
3197
3222
let restrict = self . parse_keyword ( Keyword :: RESTRICT ) ;
3198
3223
let purge = self . parse_keyword ( Keyword :: PURGE ) ;
3199
3224
if cascade && restrict {
3200
- return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in DROP" ) ;
3225
+ return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in DROP" , loc ) ;
3201
3226
}
3202
3227
if object_type == ObjectType :: Role && ( cascade || restrict || purge) {
3203
- return parser_err ! ( "Cannot specify CASCADE, RESTRICT, or PURGE in DROP ROLE" ) ;
3228
+ return parser_err ! (
3229
+ "Cannot specify CASCADE, RESTRICT, or PURGE in DROP ROLE" ,
3230
+ loc
3231
+ ) ;
3204
3232
}
3205
3233
Ok ( Statement :: Drop {
3206
3234
object_type,
@@ -4489,7 +4517,11 @@ impl<'a> Parser<'a> {
4489
4517
fn parse_literal_char ( & mut self ) -> Result < char , ParserError > {
4490
4518
let s = self . parse_literal_string ( ) ?;
4491
4519
if s. len ( ) != 1 {
4492
- return parser_err ! ( format!( "Expect a char, found {s:?}" ) ) ;
4520
+ let loc = self
4521
+ . tokens
4522
+ . get ( self . index - 1 )
4523
+ . map_or ( Location { line : 0 , column : 0 } , |t| t. location ) ;
4524
+ return parser_err ! ( format!( "Expect a char, found {s:?}" ) , loc) ;
4493
4525
}
4494
4526
Ok ( s. chars ( ) . next ( ) . unwrap ( ) )
4495
4527
}
@@ -4568,7 +4600,7 @@ impl<'a> Parser<'a> {
4568
4600
// (i.e., it returns the input string).
4569
4601
Token :: Number ( ref n, l) => match n. parse ( ) {
4570
4602
Ok ( n) => Ok ( Value :: Number ( n, l) ) ,
4571
- Err ( e) => parser_err ! ( format!( "Could not parse '{n}' as number: {e}" ) ) ,
4603
+ Err ( e) => parser_err ! ( format!( "Could not parse '{n}' as number: {e}" ) , location ) ,
4572
4604
} ,
4573
4605
Token :: SingleQuotedString ( ref s) => Ok ( Value :: SingleQuotedString ( s. to_string ( ) ) ) ,
4574
4606
Token :: DoubleQuotedString ( ref s) => Ok ( Value :: DoubleQuotedString ( s. to_string ( ) ) ) ,
@@ -6512,10 +6544,11 @@ impl<'a> Parser<'a> {
6512
6544
. parse_keywords ( & [ Keyword :: GRANTED , Keyword :: BY ] )
6513
6545
. then ( || self . parse_identifier ( ) . unwrap ( ) ) ;
6514
6546
6547
+ let loc = self . peek_token ( ) . location ;
6515
6548
let cascade = self . parse_keyword ( Keyword :: CASCADE ) ;
6516
6549
let restrict = self . parse_keyword ( Keyword :: RESTRICT ) ;
6517
6550
if cascade && restrict {
6518
- return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in REVOKE" ) ;
6551
+ return parser_err ! ( "Cannot specify both CASCADE and RESTRICT in REVOKE" , loc ) ;
6519
6552
}
6520
6553
6521
6554
Ok ( Statement :: Revoke {
@@ -8192,14 +8225,12 @@ mod tests {
8192
8225
8193
8226
#[ test]
8194
8227
fn test_parser_error_loc ( ) {
8195
- // TODO: Once we thread token locations through the parser, we should update this
8196
- // test to assert the locations of the referenced token
8197
8228
let sql = "SELECT this is a syntax error" ;
8198
8229
let ast = Parser :: parse_sql ( & GenericDialect , sql) ;
8199
8230
assert_eq ! (
8200
8231
ast,
8201
8232
Err ( ParserError :: ParserError (
8202
- "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a"
8233
+ "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a at Line: 1, Column 16 "
8203
8234
. to_string( )
8204
8235
) )
8205
8236
) ;
0 commit comments