Skip to content

Commit 097b677

Browse files
committed
Include snippet of SQL which led to parsing error
1 parent a14a3bd commit 097b677

6 files changed

+93
-71
lines changed

src/parser.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ impl<'a> Parser<'a> {
316316
pub fn try_with_sql(self, sql: &str) -> Result<Self, ParserError> {
317317
debug!("Parsing sql '{}'...", sql);
318318
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))
321321
}
322322

323323
/// Parse potentially multiple statements
@@ -2160,7 +2160,24 @@ impl<'a> Parser<'a> {
21602160

21612161
/// Report unexpected token
21622162
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: {}\nNear `{}`",
2177+
expected,
2178+
found,
2179+
TokensDisplay(near_tokens),
2180+
))
21642181
}
21652182

21662183
/// Look for an expected keyword and consume it if it exists
@@ -7756,7 +7773,7 @@ mod tests {
77567773
assert_eq!(
77577774
ast,
77587775
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\nNear `SELECT this is`"
77607777
.to_string()
77617778
))
77627779
);

tests/sqlparser_bigquery.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ fn test_select_wildcard_with_except() {
347347
.parse_sql_statements("SELECT * EXCEPT () FROM employee_table")
348348
.unwrap_err()
349349
.to_string(),
350-
"sql parser error: Expected identifier, found: )"
350+
"sql parser error: Expected identifier, found: )\nNear `SELECT * EXCEPT ()`"
351351
);
352352
}
353353

0 commit comments

Comments
 (0)