prestodb/presto · error · ParsingException
mismatched input '${offendingToken}'. Expecting: ${expected}
Error message
mismatched input '${offendingToken}'. Expecting: ${expected} What it means
This is the generic SQL parse error thrown by Presto's ANTLR error handler when a token appears that does not fit the grammar at the current position. The message shows the offending token text and a human-readable list of tokens/rules the parser expected at that point. It wraps the ANTLR failure in a ParsingException carrying the line and column.
Source
Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/ErrorHandler.java:109
Analyzer analyzer = new Analyzer(atn, parser.getVocabulary(), specialRules, specialTokens, ignoredRules, parser.getTokenStream());
Multimap<Integer, String> candidates = analyzer.process(currentState, currentToken.getTokenIndex(), context);
// pick the candidate tokens associated largest token index processed (i.e., the path that consumed the most input)
String expected = candidates.asMap().entrySet().stream()
.max(Comparator.comparing(Map.Entry::getKey))
.get()
.getValue().stream()
.sorted()
.collect(Collectors.joining(", "));
message = String.format("mismatched input '%s'. Expecting: %s", ((Token) offendingSymbol).getText(), expected);
}
catch (Exception exception) {
LOG.error(exception, "Unexpected failure when handling parsing error. This is likely a bug in the implementation");
}
throw new ParsingException(message, e, line, charPositionInLine);
}
private static class ParsingState
{
public final ATNState state;
public final int tokenIndex;
private final CallerContext caller;
public ParsingState(ATNState state, int tokenIndex, CallerContext caller)
{
this.state = state;
this.tokenIndex = tokenIndex;
this.caller = caller;
}
}
private static class CallerContext
{View on GitHub (pinned to 55bb57d202)
Solutions
- Read the 'Expecting:' list in the message and insert/fix the token at the reported line:column
- Quote identifiers with double quotes if they collide with reserved keywords
- Run the SQL through a linter or the parser in a test before executing
- Check for dialect-specific syntax not supported by Presto
Example fix
// before String sql = "SELECT name age FROM users"; // mismatched input 'FROM'. Expecting: ',' // after String sql = "SELECT name, age FROM users";
Defensive patterns
Strategy: try-catch
Validate before calling
// Best-effort balance check before parsing
long opens = sql.chars().filter(c -> c == '(').count();
long closes = sql.chars().filter(c -> c == ')').count();
if (opens != closes) throw new IllegalArgumentException("Unbalanced parentheses in SQL"); Type guard
boolean isLikelyPrestoSql(String sql) {
return sql != null && !sql.trim().isEmpty()
&& !sql.contains("`") // no MySQL backticks
&& sql.replaceAll("'[^']*'", "").chars()
.noneMatch(c -> "!@$^{}".indexOf(c) >= 0);
} Try / catch
try {
Statement stmt = sqlParser.createStatement(sql);
} catch (ParsingException e) {
// e.getErrorMessage(), e.getLineNumber(), e.getColumnNumber()
log.error("SQL syntax error at %d:%d: %s", e.getLineNumber(), e.getColumnNumber(), e.getErrorMessage());
throw new QueryValidationError(sql, e);
} Prevention
- Quote identifiers with double quotes, never backticks
- Lint generated SQL in CI with the same parser
- Avoid string-concatenating SQL fragments
- Keep a dialect map when porting queries from MySQL/T-SQL
When it happens
Trigger: Calling SqlParser.createStatement/createExpression with SQL containing a typo, misplaced keyword, missing operator, or a construct the grammar does not allow — e.g. 'SELECT FROM t', 'SELECT a b FROM t'.
Common situations: Hand-written SQL built by string concatenation, copy-pasted SQL from other dialects (MySQL backticks, T-SQL TOP), missing commas/parentheses, reserved words used as identifiers.
Related errors
- ${name} is too large (stack overflow while parsing)
- identifiers must not contain '${symbol}'
- identifiers must not start with a digit; surround the identi
- INVALID_TABLE_PROPERTY
- MISSING_ATTRIBUTE
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/de7fc116aa9bb6a7.
Report an issue: GitHub.