@@ -316,8 +316,8 @@ impl<'a> Parser<'a> {
316
316
pub fn try_with_sql ( self , sql : & str ) -> Result < Self , ParserError > {
317
317
debug ! ( "Parsing sql '{}'..." , sql) ;
318
318
let mut tokenizer = Tokenizer :: new ( self . dialect , sql) ;
319
- let tokens = tokenizer. tokenize ( ) ?;
320
- Ok ( self . with_tokens ( tokens) )
319
+ let tokens = tokenizer. tokenize_with_location ( ) ?;
320
+ Ok ( self . with_tokens_with_locations ( tokens) )
321
321
}
322
322
323
323
/// Parse potentially multiple statements
@@ -2160,7 +2160,24 @@ impl<'a> Parser<'a> {
2160
2160
2161
2161
/// Report unexpected token
2162
2162
pub fn expected < T > ( & self , expected : & str , found : TokenWithLocation ) -> Result < T , ParserError > {
2163
- parser_err ! ( format!( "Expected {expected}, found: {found}" ) )
2163
+ let start_off = self . index . saturating_sub ( 10 ) ;
2164
+ let end_off = self . index . min ( self . tokens . len ( ) ) ;
2165
+ let near_tokens = & self . tokens [ start_off..end_off] ;
2166
+ struct TokensDisplay < ' a > ( & ' a [ TokenWithLocation ] ) ;
2167
+ impl < ' a > fmt:: Display for TokensDisplay < ' a > {
2168
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2169
+ for token in self . 0 {
2170
+ write ! ( f, "{}" , token) ?;
2171
+ }
2172
+ Ok ( ( ) )
2173
+ }
2174
+ }
2175
+ parser_err ! ( format!(
2176
+ "Expected {}, found: {}\n Near `{}`" ,
2177
+ expected,
2178
+ found,
2179
+ TokensDisplay ( near_tokens) ,
2180
+ ) )
2164
2181
}
2165
2182
2166
2183
/// Look for an expected keyword and consume it if it exists
@@ -7756,7 +7773,7 @@ mod tests {
7756
7773
assert_eq ! (
7757
7774
ast,
7758
7775
Err ( ParserError :: ParserError (
7759
- "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a"
7776
+ "Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: a\n Near `SELECT this is` "
7760
7777
. to_string( )
7761
7778
) )
7762
7779
) ;
0 commit comments