{"record":{"id":"de7fc116aa9bb6a7","repo":"prestodb/presto","slug":"mismatched-input-offendingtoken-expecting","errorCode":null,"errorMessage":"mismatched input '${offendingToken}'. Expecting: ${expected}","messagePattern":"mismatched input '(.+?)'\\. Expecting: (.+?)","errorType":"exception","errorClass":"ParsingException","httpStatus":null,"severity":"error","filePath":"presto-parser/src/main/java/com/facebook/presto/sql/parser/ErrorHandler.java","lineNumber":109,"sourceCode":"\n            Analyzer analyzer = new Analyzer(atn, parser.getVocabulary(), specialRules, specialTokens, ignoredRules, parser.getTokenStream());\n            Multimap<Integer, String> candidates = analyzer.process(currentState, currentToken.getTokenIndex(), context);\n\n            // pick the candidate tokens associated largest token index processed (i.e., the path that consumed the most input)\n            String expected = candidates.asMap().entrySet().stream()\n                    .max(Comparator.comparing(Map.Entry::getKey))\n                    .get()\n                    .getValue().stream()\n                    .sorted()\n                    .collect(Collectors.joining(\", \"));\n\n            message = String.format(\"mismatched input '%s'. Expecting: %s\", ((Token) offendingSymbol).getText(), expected);\n        }\n        catch (Exception exception) {\n            LOG.error(exception, \"Unexpected failure when handling parsing error. This is likely a bug in the implementation\");\n        }\n\n        throw new ParsingException(message, e, line, charPositionInLine);\n    }\n\n    private static class ParsingState\n    {\n        public final ATNState state;\n        public final int tokenIndex;\n        private final CallerContext caller;\n\n        public ParsingState(ATNState state, int tokenIndex, CallerContext caller)\n        {\n            this.state = state;\n            this.tokenIndex = tokenIndex;\n            this.caller = caller;\n        }\n    }\n\n    private static class CallerContext\n    {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parser/src/main/java/com/facebook/presto/sql/parser/ErrorHandler.java#L91-L127","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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"],"exampleFix":"// before\nString sql = \"SELECT name age FROM users\"; // mismatched input 'FROM'. Expecting: ','\n// after\nString sql = \"SELECT name, age FROM users\";","handlingStrategy":"try-catch","validationCode":"// Best-effort balance check before parsing\nlong opens = sql.chars().filter(c -> c == '(').count();\nlong closes = sql.chars().filter(c -> c == ')').count();\nif (opens != closes) throw new IllegalArgumentException(\"Unbalanced parentheses in SQL\");","typeGuard":"boolean isLikelyPrestoSql(String sql) {\n    return sql != null && !sql.trim().isEmpty()\n        && !sql.contains(\"`\")   // no MySQL backticks\n        && sql.replaceAll(\"'[^']*'\", \"\").chars()\n             .noneMatch(c -> \"!@$^{}\".indexOf(c) >= 0);\n}","tryCatchPattern":"try {\n    Statement stmt = sqlParser.createStatement(sql);\n} catch (ParsingException e) {\n    // e.getErrorMessage(), e.getLineNumber(), e.getColumnNumber()\n    log.error(\"SQL syntax error at %d:%d: %s\", e.getLineNumber(), e.getColumnNumber(), e.getErrorMessage());\n    throw new QueryValidationError(sql, e);\n}","preventionTips":["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"],"tags":["sql","parser","syntax-error"],"backgroundTag":"sql-syntax-error","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}