prestodb/presto · error · ParsingException

identifiers must not contain '${symbol}'

Error message

identifiers must not contain '${symbol}'

What it means

After parsing, PostProcessor.exitUnquotedIdentifier validates unquoted identifier text against the set of allowed identifier symbols. If the identifier contains a disallowed character (the complement of allowedIdentifierSymbols), a ParsingException is thrown naming the offending symbol. This enforces which punctuation may appear bare inside identifiers.

Source

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

            extends SqlBaseBaseListener
    {
        private final List<String> ruleNames;
        private final Consumer<ParsingWarning> warningConsumer;

        public PostProcessor(List<String> ruleNames, Consumer<ParsingWarning> warningConsumer)
        {
            this.ruleNames = ruleNames;
            this.warningConsumer = requireNonNull(warningConsumer, "warningConsumer is null");
        }

        @Override
        public void exitUnquotedIdentifier(SqlBaseParser.UnquotedIdentifierContext context)
        {
            String identifier = context.IDENTIFIER().getText();
            for (IdentifierSymbol identifierSymbol : EnumSet.complementOf(allowedIdentifierSymbols)) {
                char symbol = identifierSymbol.getSymbol();
                if (identifier.indexOf(symbol) >= 0) {
                    throw new ParsingException("identifiers must not contain '" + identifierSymbol.getSymbol() + "'", null, context.IDENTIFIER().getSymbol().getLine(), context.IDENTIFIER().getSymbol().getCharPositionInLine());
                }
            }
        }

        @Override
        public void exitBackQuotedIdentifier(SqlBaseParser.BackQuotedIdentifierContext context)
        {
            Token token = context.BACKQUOTED_IDENTIFIER().getSymbol();
            throw new ParsingException(
                    "backquoted identifiers are not supported; use double quotes to quote identifiers",
                    null,
                    token.getLine(),
                    token.getCharPositionInLine());
        }

        @Override
        public void exitDigitIdentifier(SqlBaseParser.DigitIdentifierContext context)
        {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Wrap the identifier in double quotes: "a.b.c"
  2. Remove the offending character from the identifier
  3. Parse with parser options/initializer that allow the needed identifier symbol if applicable

Example fix

// before
String sql = "SELECT my.column FROM t"; // identifiers must not contain '.'
// after
String sql = "SELECT \"my.column\" FROM t";
Defensive patterns

Strategy: validation

Validate before calling

// Verify unquoted identifiers contain only allowed characters before building SQL
Pattern OK = Pattern.compile("[A-Za-z_][A-Za-z0-9_$]*");
if (!OK.matcher(identifier).matches()) {
    identifier = '"' + identifier.replace("\"", "\"\"") + '"';
}

Type guard

boolean isSafeUnquotedIdentifier(String id) {
    return id != null && id.matches("[A-Za-z_][A-Za-z0-9_]*");
}

Try / catch

try {
    return sqlParser.createStatement(sql);
} catch (ParsingException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("identifiers must not contain")) {
        throw new IdentifierQuotingRequiredException(e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: An unquoted identifier containing characters like '.' or other disallowed symbols in an unrestricted parse — e.g. SELECT a.b.c interpreted as one unquoted token in a context where such symbols are not allowed.

Common situations: Copy-pasted qualified names from other systems, identifiers pasted with trailing punctuation, parsing fragments where dot-containing names were meant to be quoted.

Related errors


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