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

  1. Read the 'Expecting:' list in the message and insert/fix the token at the reported line:column
  2. Quote identifiers with double quotes if they collide with reserved keywords
  3. Run the SQL through a linter or the parser in a test before executing
  4. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/de7fc116aa9bb6a7. Report an issue: GitHub.