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
- Wrap the identifier in double quotes: "a.b.c"
- Remove the offending character from the identifier
- 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
- Always double-quote identifiers that contain dots or special characters
- Escape embedded double quotes by doubling them
- Whitelist identifier characters in query-building helpers
- Never paste qualified names as a single bare identifier
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
- identifiers must not start with a digit; surround the identi
- mismatched input '${offendingToken}'. Expecting: ${expected}
- ${name} is too large (stack overflow while parsing)
- backquoted identifiers are not supported; use double quotes
- INVALID_TABLE_PROPERTY
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/016b05cdae72508c.
Report an issue: GitHub.