prestodb/presto · error · ParsingException

${lexerErrorMessage}

Error message

${lexerErrorMessage}

What it means

This is the lexer-level error path: when the SQL tokenizer (SqlBaseLexer) cannot produce any token for the input, its BaseErrorListener immediately throws a ParsingException with the ANTLR lexer message, line, and column. Unlike parser errors, this fires on characters that cannot start any known token.

Source

Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/SqlParser.java:55

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

import static com.facebook.presto.sql.parser.SqlParserOptions.RESERVED_WORDS_WARNING;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

public class SqlParser
{
    private static final BaseErrorListener LEXER_ERROR_LISTENER = new BaseErrorListener()
    {
        @Override
        public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String message, RecognitionException e)
        {
            throw new ParsingException(message, e, line, charPositionInLine);
        }
    };
    private static final BiConsumer<SqlBaseLexer, SqlBaseParser> DEFAULT_PARSER_INITIALIZER = (SqlBaseLexer lexer, SqlBaseParser parser) -> {};

    private static final ErrorHandler PARSER_ERROR_HANDLER = ErrorHandler.builder()
            .specialRule(SqlBaseParser.RULE_expression, "<expression>")
            .specialRule(SqlBaseParser.RULE_booleanExpression, "<expression>")
            .specialRule(SqlBaseParser.RULE_valueExpression, "<expression>")
            .specialRule(SqlBaseParser.RULE_primaryExpression, "<expression>")
            .specialRule(SqlBaseParser.RULE_identifier, "<identifier>")
            .specialRule(SqlBaseParser.RULE_string, "<string>")
            .specialRule(SqlBaseParser.RULE_query, "<query>")
            .specialRule(SqlBaseParser.RULE_type, "<type>")
            .specialToken(SqlBaseLexer.INTEGER_VALUE, "<integer>")
            .ignoredRule(SqlBaseParser.RULE_nonReserved)
            .build();

    private final BiConsumer<SqlBaseLexer, SqlBaseParser> initializer;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the character at the reported line/column and remove or fix it
  2. Terminate any unterminated string literal with a closing quote
  3. Replace non-ASCII smart quotes with plain quotes
  4. Substitute templating placeholders before parsing

Example fix

// before
String sql = "SELECT 'abc FROM t"; // unterminated string literal
// after
String sql = "SELECT 'abc' FROM t";
Defensive patterns

Strategy: try-catch

Validate before calling

// Reject obvious lexer hazards: unbalanced quotes and stray control chars
int quotes = 0;
for (char c : sql.toCharArray()) if (c == '\'') quotes++;
if (quotes % 2 != 0) throw new IllegalArgumentException("Unterminated string literal");

Type guard

boolean isLexerSafe(String sql) {
    return sql != null && sql.chars().noneMatch(c -> c < 0x20 && c != '\n' && c != '\t')
        && sql.replace("\\'", "").chars().filter(c -> c == '\'').count() % 2 == 0;
}

Try / catch

try {
    Statement stmt = sqlParser.createStatement(sql);
} catch (ParsingException e) {
    log.error("Lexer failure at line %d col %d: %s", e.getLineNumber(), e.getColumnNumber(), e.getErrorMessage());
    throw new QueryValidationError(sql, e);
}

Prevention

When it happens

Trigger: Passing SQL containing invalid characters to SqlParser — e.g. stray '!', '@', '$', a single quote opening an unterminated string literal, or an unencodable character.

Common situations: Template placeholders (${}, ?, :) left unsubstituted in SQL strings, smart quotes from rich-text editors, broken string escaping producing a dangling quote.

Related errors


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